質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

[Python3] tkinter, 緊急停止ボタンの作成に関して教えてください

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 835

score 23

■やりたいこと
1、 ラジオボタンにて帯域を選択したあと、チェックボックスを選択し、
【測定開始】ボタンを押した際に、常に前面に表示されるウィンドウを作りたい。

2、 サブウィンドウの中に「停止」ボタンを作りたい(ボタン作成のコードは作成したが反映しない)

■現状
【測定開始】ボタンを押した際に、一番最初に表示させたいサブウィンドウが、一番最後に表示されてしまう。
サブウィンドウの中に一つボタンを作りたいのだが、コードが反映していない。

from tkinter import *
from tkinter import ttk
from time import sleep

root = Tk()
root.title('測定CH設定')    
root.geometry("500x860+710+40")

Lframe1 = ttk.Labelframe(root, text='測定帯域選択', padding=5)
Lframe1.grid(row=0, column=0, columnspan=1, padx=15, pady=10, sticky='w')
Lframe2 = ttk.Labelframe(root, text='2.4GHz',padding=5)
Lframe2.grid(row=1,column=0, columnspan=1, padx=15, pady=10, sticky='nw')
Lframe3 = ttk.Labelframe(root, text='5GHz',padding=5)
Lframe3.grid(row=1,column=1, columnspan=1, padx=10, pady=10, sticky='w')

selected_frame = IntVar()

def change_selected_frame():
    if selected_frame.get() == 0:

        for child in Lframe2.winfo_children():
            child.configure(state='enable')
        for child in Lframe3.winfo_children():
            child.configure(state='disable')

    elif selected_frame.get() == 1:
        for child in Lframe2.winfo_children():
            child.configure(state='disable')
        for child in Lframe3.winfo_children():
            child.configure(state='enable')

    else:
        for child in Lframe2.winfo_children():
            child.configure(state='disable')
        for child in Lframe3.winfo_children():
            child.configure(state='disable')

Rbutton1 = ttk.Radiobutton(Lframe1, text='2.4GHz ', variable=selected_frame, value=0, command=change_selected_frame)
Rbutton1.grid(row=1,column=0,pady=5)
Rbutton2 = ttk.Radiobutton(Lframe1,text='5GHz', variable=selected_frame, value=1, command=change_selected_frame)
Rbutton2.grid(row=1,column=1,pady=5)

class val_2G:
    def __init__(self,name,set_frame,row_no):
        self.bool=BooleanVar()
        self.bool.set(False)
        self.name=name
        self.Cbtn=ttk.Checkbutton(set_frame, text=self.name, variable=self.bool)
        self.Cbtn.grid(row=row_no,column=0, columnspan=1, padx=15, pady=5, sticky='w')

class val_5G:
    def __init__(self,name,set_frame,row_no):
        self.bool=BooleanVar()
        self.bool.set(False)
        self.name=name
        self.Cbtn=ttk.Checkbutton(set_frame, text=self.name, variable=self.bool)
        self.Cbtn.grid(row=row_no,column=0, columnspan=1, padx=15, pady=5, sticky='w')

val_2G1=val_2G('CH1',Lframe2,6)
val_2G2=val_2G('CH2',Lframe2,7)
val_2G3=val_2G('CH3',Lframe2,8)
val_2G4=val_2G('CH4',Lframe2,9)
val_2G5=val_2G('CH5',Lframe2,10)
val_2G6=val_2G('CH6',Lframe2,11)
val_2G7=val_2G('CH7',Lframe2,12)
val_2G8=val_2G('CH8',Lframe2,13)
val_2G9=val_2G('CH9',Lframe2,14)
val_2G10=val_2G('CH10',Lframe2,15)
val_2G11=val_2G('CH11',Lframe2,16)
val_2G12=val_2G('CH12',Lframe2,17)
val_2G13=val_2G('CH13',Lframe2,18)
val_2G_list=[val_2G1, val_2G2, val_2G3, val_2G4, val_2G5, val_2G6, val_2G7, val_2G8, val_2G9, val_2G10, val_2G11, val_2G12, val_2G13]

val_5G36=val_5G('CH36',Lframe3,6)
val_5G40=val_5G('CH40',Lframe3,7)
val_5G44=val_5G('CH44',Lframe3,8)
val_5G48=val_5G('CH48',Lframe3,9)
val_5G52=val_5G('CH52',Lframe3,10)
val_5G56=val_5G('CH56',Lframe3,11)
val_5G60=val_5G('CH60',Lframe3,12)
val_5G64=val_5G('CH64',Lframe3,13)
val_5G100=val_5G('CH100',Lframe3,14)
val_5G104=val_5G('CH104',Lframe3,15)
val_5G108=val_5G('CH108',Lframe3,16)
val_5G112=val_5G('CH112',Lframe3,17)
val_5G116=val_5G('CH116',Lframe3,18)
val_5G120=val_5G('CH120',Lframe3,19)
val_5G124=val_5G('CH124',Lframe3,20)
val_5G128=val_5G('CH128',Lframe3,21)
val_5G132=val_5G('CH132',Lframe3,22)
val_5G136=val_5G('CH136',Lframe3,23)
val_5G140=val_5G('CH140',Lframe3,24)
val_5G_list=[val_5G36, val_5G40, val_5G44, val_5G48, val_5G52, val_5G56,val_5G60, val_5G64, val_5G100, val_5G104, val_5G108, val_5G112, val_5G116, val_5G120, val_5G124, val_5G128, val_5G132, val_5G136, val_5G140]


def check_all_2G_checkboxes():
    for val in val_2G_list:
        val.bool.set(True)

def clear_all_2G_checkboxes():
    for val in val_2G_list:
        val.bool.set(False)

def check_all_5G_checkboxes():
    for val in val_5G_list:
        val.bool.set(True)

def clear_all_5G_checkboxes():
    for val in val_5G_list:
        val.bool.set(False) 

def sub_window():
    sub_window = Toplevel()
    sub_window.title('緊急停止')
    sub_window.attributes("-topmost", True)
    sub_window.geometry("600x300+660+400")
    btn = ttk.Button(text='停止', padding=5)      ##ボタンが作成されない

def check_box():
    global checkbox

    sub_window()        ##一番最初に表示し緊急停止ボタンのように動かしたいのだが、一番最後に表示されてしまう

    selected_channels2 = []
    selected_channels5 = []

    if selected_frame.get() == 0:
        for val in val_2G_list:
            if val.bool.get():
                selected_channels2.append(val.name)

    elif selected_frame.get() == 1:
        for val in val_5G_list:
            if val.bool.get():
                selected_channels5.append(val.name)

    if len(selected_channels2) > 0:
        measure_channels2(selected_channels2)

    elif len(selected_channels5) > 0:
        measure_channels5(selected_channels5)

def measure_channels2(channels2):
    for channel2 in channels2:
        ch2 = channel2[2:]
        print(f'チャンネル {ch2} を測定中')
        sleep(5)
        print("測定終了")

def measure_channels5(channels5):
    for channel5 in channels5:
        ch5 = channel5[2:]
        print(f'チャンネル {ch5} を測定中')
        sleep(5)
        print("測定終了")

def quit():
    global checkbox
    checkbox.destroy()

btn1 = ttk.Button(Lframe2, text='全選択', padding=5, command=check_all_2G_checkboxes)
btn1.grid(row=5,column=0,pady=5)
btn2 = ttk.Button(Lframe2, text='全解除', padding=5, command=clear_all_2G_checkboxes)
btn2.grid(row=5,column=1,pady=5)
btn3 = ttk.Button(Lframe3, text='全選択', padding=5, command=check_all_5G_checkboxes)
btn3.grid(row=5,column=0,pady=5)
btn4 = ttk.Button(Lframe3, text='全解除', padding=5, command=clear_all_5G_checkboxes)
btn4.grid(row=5,column=1,pady=5)
btn5 = ttk.Button(text='測定開始', padding=5, command=check_box)
btn5.grid(row=5,column=0,pady=5)
btn6 = ttk.Button(text='キャンセル', padding=5, command=quit)
btn6.grid(row=5,column=1,pady=5)
selected_frame.set(-1) 
change_selected_frame() 

root.mainloop()

記述方法ご存知の方いらっしゃいましたら、ご教授頂けると幸いです。
よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

イベント処理が終わらないと描画処理が動けないため、処理が終わったあとにウィンドウが表示されます。
時間のかかる処理を別スレッドにして、イベント処理をさっさと終わらせるといいです。

from tkinter import *
from tkinter import ttk
from time import sleep
from threading import Thread


class WifiChecker:

    def __init__(self, selected_frame, val_2G_list, val_5G_list, stopped):
        self.selected_frame = selected_frame
        self.val_2G_list = val_2G_list
        self.val_5G_list = val_5G_list
        self.stopped = stopped
        self.running = False

    def start(self):
        self.running = True

        if self.selected_frame.get() == 0:
            selected_channels2 = []
            for val in self.val_2G_list:
                if val.bool.get():
                    selected_channels2.append(val.name)
            self.measure_channels2(selected_channels2)

        elif self.selected_frame.get() == 1:
            selected_channels5 = []
            for val in self.val_5G_list:
                if val.bool.get():
                    selected_channels5.append(val.name)
            self.measure_channels5(selected_channels5)

        self.stop()
        self.stopped()

    def stop(self):
        self.running = False

    def measure_channels2(self, channels2):
        for channel2 in channels2:
            if not self.running:
                return
            ch2 = channel2[2:]
            print(f'チャンネル {ch2} を測定中')
            sleep(5)
            print("測定終了")

    def measure_channels5(self, channels5):
        for channel5 in channels5:
            if not self.running:
                return
            ch5 = channel5[2:]
            print(f'チャンネル {ch5} を測定中')
            sleep(5)
            print("測定終了")


def show_main_window(window):
    window.title('測定CH設定')
    window.geometry("500x860+710+40")

    Lframe1 = ttk.Labelframe(window, text='測定帯域選択', padding=5)
    Lframe1.grid(row=0, column=0, columnspan=1, padx=15, pady=10, sticky='w')
    Lframe2 = ttk.Labelframe(window, text='2.4GHz', padding=5)
    Lframe2.grid(row=1, column=0, columnspan=1, padx=15, pady=10, sticky='nw')
    Lframe3 = ttk.Labelframe(window, text='5GHz', padding=5)
    Lframe3.grid(row=1, column=1, columnspan=1, padx=10, pady=10, sticky='w')

    selected_frame = IntVar()

    def change_selected_frame():
        if selected_frame.get() == 0:
            for child in Lframe2.winfo_children():
                child.configure(state='enable')
            for child in Lframe3.winfo_children():
                child.configure(state='disable')

        elif selected_frame.get() == 1:
            for child in Lframe2.winfo_children():
                child.configure(state='disable')
            for child in Lframe3.winfo_children():
                child.configure(state='enable')

        else:
            for child in Lframe2.winfo_children():
                child.configure(state='disable')
            for child in Lframe3.winfo_children():
                child.configure(state='disable')

    Rbutton1 = ttk.Radiobutton(
        Lframe1, text='2.4GHz ', variable=selected_frame, value=0, command=change_selected_frame)
    Rbutton1.grid(row=1, column=0, pady=5)
    Rbutton2 = ttk.Radiobutton(
        Lframe1, text='5GHz', variable=selected_frame, value=1, command=change_selected_frame)
    Rbutton2.grid(row=1, column=1, pady=5)

    class val_2G:
        def __init__(self, name, set_frame, row_no):
            self.bool = BooleanVar()
            self.bool.set(False)
            self.name = name
            self.Cbtn = ttk.Checkbutton(
                set_frame, text=self.name, variable=self.bool)
            self.Cbtn.grid(row=row_no, column=0, columnspan=1,
                           padx=15, pady=5, sticky='w')

    class val_5G:
        def __init__(self, name, set_frame, row_no):
            self.bool = BooleanVar()
            self.bool.set(False)
            self.name = name
            self.Cbtn = ttk.Checkbutton(
                set_frame, text=self.name, variable=self.bool)
            self.Cbtn.grid(row=row_no, column=0, columnspan=1,
                           padx=15, pady=5, sticky='w')

    val_2G1 = val_2G('CH1', Lframe2, 6)
    val_2G2 = val_2G('CH2', Lframe2, 7)
    val_2G3 = val_2G('CH3', Lframe2, 8)
    val_2G4 = val_2G('CH4', Lframe2, 9)
    val_2G5 = val_2G('CH5', Lframe2, 10)
    val_2G6 = val_2G('CH6', Lframe2, 11)
    val_2G7 = val_2G('CH7', Lframe2, 12)
    val_2G8 = val_2G('CH8', Lframe2, 13)
    val_2G9 = val_2G('CH9', Lframe2, 14)
    val_2G10 = val_2G('CH10', Lframe2, 15)
    val_2G11 = val_2G('CH11', Lframe2, 16)
    val_2G12 = val_2G('CH12', Lframe2, 17)
    val_2G13 = val_2G('CH13', Lframe2, 18)
    val_2G_list = [val_2G1, val_2G2, val_2G3, val_2G4, val_2G5, val_2G6,
                   val_2G7, val_2G8, val_2G9, val_2G10, val_2G11, val_2G12, val_2G13]

    val_5G36 = val_5G('CH36', Lframe3, 6)
    val_5G40 = val_5G('CH40', Lframe3, 7)
    val_5G44 = val_5G('CH44', Lframe3, 8)
    val_5G48 = val_5G('CH48', Lframe3, 9)
    val_5G52 = val_5G('CH52', Lframe3, 10)
    val_5G56 = val_5G('CH56', Lframe3, 11)
    val_5G60 = val_5G('CH60', Lframe3, 12)
    val_5G64 = val_5G('CH64', Lframe3, 13)
    val_5G100 = val_5G('CH100', Lframe3, 14)
    val_5G104 = val_5G('CH104', Lframe3, 15)
    val_5G108 = val_5G('CH108', Lframe3, 16)
    val_5G112 = val_5G('CH112', Lframe3, 17)
    val_5G116 = val_5G('CH116', Lframe3, 18)
    val_5G120 = val_5G('CH120', Lframe3, 19)
    val_5G124 = val_5G('CH124', Lframe3, 20)
    val_5G128 = val_5G('CH128', Lframe3, 21)
    val_5G132 = val_5G('CH132', Lframe3, 22)
    val_5G136 = val_5G('CH136', Lframe3, 23)
    val_5G140 = val_5G('CH140', Lframe3, 24)
    val_5G_list = [val_5G36, val_5G40, val_5G44, val_5G48, val_5G52, val_5G56, val_5G60, val_5G64, val_5G100,
                   val_5G104, val_5G108, val_5G112, val_5G116, val_5G120, val_5G124, val_5G128, val_5G132, val_5G136, val_5G140]

    def check_all_2G_checkboxes():
        for val in val_2G_list:
            val.bool.set(True)

    def clear_all_2G_checkboxes():
        for val in val_2G_list:
            val.bool.set(False)

    def check_all_5G_checkboxes():
        for val in val_5G_list:
            val.bool.set(True)

    def clear_all_5G_checkboxes():
        for val in val_5G_list:
            val.bool.set(False)

    def start():
        def stopped():
            stopper.destroy()
        checker = WifiChecker(selected_frame, val_2G_list, val_5G_list, stopped)
        stopper = show_stop_window(checker)
        thread = Thread(target=checker.start)
        thread.start()

    def quit():
        window.destroy()

    btn1 = ttk.Button(Lframe2, text='全選択', padding=5,
                      command=check_all_2G_checkboxes)
    btn1.grid(row=5, column=0, pady=5)
    btn2 = ttk.Button(Lframe2, text='全解除', padding=5,
                      command=clear_all_2G_checkboxes)
    btn2.grid(row=5, column=1, pady=5)
    btn3 = ttk.Button(Lframe3, text='全選択', padding=5,
                      command=check_all_5G_checkboxes)
    btn3.grid(row=5, column=0, pady=5)
    btn4 = ttk.Button(Lframe3, text='全解除', padding=5,
                      command=clear_all_5G_checkboxes)
    btn4.grid(row=5, column=1, pady=5)
    btn5 = ttk.Button(text='測定開始', padding=5, command=start)
    btn5.grid(row=5, column=0, pady=5)
    btn6 = ttk.Button(text='キャンセル', padding=5, command=quit)
    btn6.grid(row=5, column=1, pady=5)
    selected_frame.set(-1)
    change_selected_frame()


def show_stop_window(checker):
    sub_window = Toplevel()
    sub_window.title('緊急停止')
    sub_window.attributes("-topmost", True)
    sub_window.geometry("600x300+660+400")
    btn = ttk.Button(sub_window, text='停止', padding=5, command=checker.stop)
    btn.pack()
    return sub_window


def main():
    root = Tk()
    show_main_window(root)
    root.mainloop()


if __name__ == '__main__':
    main()

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/12/03 16:05

    shiracamusさん、どうもありがとうございました!仕様的にベストアンサーがつけられない状態です。もうしわけございません。回答、参考にさせていただきます。ありがとうございました。

    キャンセル

check解決した方法

-1

解決方法(自己解決の場合のみ記入してください)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る