0

画面上にTkinterウィンドウを動的に作成したい。mainloop()は1つだけにする必要があることを理解しています。スレッドモジュールを使用して、メインループを別のスレッドで実行するので、スクリプトがブロックされません。

mainloopを実行した後、Tkinterウィンドウをさらに作成するにはどうすればよいですか?

私のコードを見てください:

from Tkinter import *
import threading
import time

class box:
    def __init__(self, pos):
        self.master = Tk()
        self.master.geometry(pos) 
        self.canvas = Canvas(self.master, width=50, height=50, highlightthickness=0 )
        self.canvas.pack()
        self.rect = self.canvas.create_rectangle(0, 0, 50, 50, fill="red", outline="red")
        self.text = self.canvas.create_text(25, 24, text="99",fill="white", font=("calibri", 24, "bold"))

    def changeFill(self, color):
        self.canvas.itemconfig(self.rect, fill=color, outline=color) # change color

class box_manager(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.boxes = {}
        self.add_box(1, "50x50+300+300")
        self.add_box(2, "50x50+100+100")
    def add_box(self, num, pos):
        self.boxes[num] = box(pos)
    def run(self):
        mainloop()

tk = box_manager()
tk.start()

# How do I dynamically add new tkinter windows? the line below makes python.exe crash.
tk.add_box(3, "50x50+200+200")

Joelのコメントの後に更新しても、まだ機能しません。

from Tkinter import *
import threading
import time

class MyCustomWindow(Toplevel):
    def __init__(self):
        Toplevel.__init__(self)
        #setup goes here
        self.geometry("50x50+100+100") 
        self.canvas = Canvas(self, width=50, height=50, highlightthickness=0 )
        self.canvas.pack()

class App(Tk):

    def CreateFirst(self):
        self.anotherWindow = MyCustomWindow()
    def CreateSecond(self):
        self.secondWindow = MyCustomWindow()


class SecondWindow(threading.Thread):
    #after 2 seconds create a second window, python.exe crashes
    def run(self):
        time.sleep(2)
        tk.CreateSecond()

SecondWindow().start()
tk = App()
tk.CreateFirst()
mainloop()  
4

2 に答える 2

5

mainloopを実行した後、Tkinterウィンドウをさらに作成するにはどうすればよいですか?

あなたはそうしない。それはTkinterが機能するように設計されている方法ではありません。mainloopは、常にメインスレッドから1回だけ呼び出す必要があります。

于 2013-01-15T12:07:11.470 に答える
3

追加の(ルート以外の)ウィンドウは単なるToplevelウィジェットです。単純にサブクラス化Toplevelし、メインクラス内から呼び出します。

class MyCustomWindow(tkinter.Toplevel):
    def __init__(self):
        tkinter.Toplevel.__init__(self)
        #setup goes here


class App(tkinter.Tk):

    def someCallback(self):
        self.anotherWindow = MyCustomWindow()

編集

もちろんサブクラスにする必要はありませんToplevel直接使用できます。

于 2013-01-15T12:13:25.047 に答える