使用tkinter python运行多线程

使用tkinter python运行多线程,python,multithreading,tkinter,Python,Multithreading,Tkinter,我正在运行带有多线程的tkinter GUI。但是,窗口右上角的“开/关”按钮在执行时隐藏。它只在我单击一次时出现。但是,当我在mainloop外编写threading()函数时,它可以工作,但只有在关闭GUI时才会显示错误“mainloop外的主线程” 这段代码实际上是一段更大的代码的一部分,在这段代码中除了canvas之外还有很多小部件。加载GUI需要时间。因此,我认为我应该使用线程 from tkinter import * from tkinter import Canvas,Frame

我正在运行带有多线程的tkinter GUI。但是,窗口右上角的“开/关”按钮在执行时隐藏。它只在我单击一次时出现。但是,当我在mainloop外编写threading()函数时,它可以工作,但只有在关闭GUI时才会显示错误“mainloop外的主线程” 这段代码实际上是一段更大的代码的一部分,在这段代码中除了canvas之外还有很多小部件。加载GUI需要时间。因此,我认为我应该使用线程

from tkinter import *
from tkinter import Canvas,Frame,BOTH
from PIL import ImageTk, Image
from threading import *

class GUI:
    def __init__(self,t):
        self.t=t
    def canvas(self,t):
        canvas = Canvas(t, height = 1080, width= 720)
        canvas.create_line(0, 615,1400,615,width=5)
        canvas.create_line(0,20,1400,20,width=5)
        canvas.create_rectangle(0, 0, 1400, 20, fill='cornsilk2')
        canvas.create_rectangle(0, 615, 260, 635, fill='cornsilk2')
        canvas.create_rectangle(0, 635, 260, 655, fill='cornsilk2')
        canvas.create_rectangle(0, 655, 260, 675, fill='cornsilk2')
        canvas.create_rectangle(0, 675, 260, 695, fill='cornsilk2')
        canvas.create_rectangle(1100, 615, 1400, 635, fill='cornsilk2')
        canvas.create_rectangle(1100, 635, 1400, 655, fill='cornsilk2')
        canvas.create_rectangle(1100, 655, 1400, 675, fill='cornsilk2')
        canvas.create_rectangle(1100, 675, 1400, 695, fill='cornsilk2')
        canvas.create_oval(1200, 638 , 1210,648, fill="blue")
        canvas.create_oval(1275, 638 , 1285,648, fill="blue")
        canvas.create_oval(1340, 638 , 1350,648, fill="blue")
        lmain = Label(canvas)
        lmain.pack(pady=20)
        canvas.pack(fill=BOTH,expand=1)
m=True
def control(g,t):
    
    global m
      
    # Determin is on or off
    if m:
        h.config(image = off)
        m= False
        
    else:
        h.config(image = on)
        m = True
        
def gui(G,t):
    G.canvas(t)
def threading1():
    t=Thread(target=gui(G,tk))
    t.start()
def threading():
    t3=Thread(target=control(G,tk))
    t3.start()

tk = Tk()
tk.geometry("1080x720")
tk.configure(bg="white")
tk.title("  FIREFIX CONTROL:")
p = PhotoImage(file = 'S:\Ideas\Fire safety Bot\F.png')
tk.iconphoto(False,p)
G=GUI(tk)
threading1()
on=Image.open(r"S:\Ideas\Fire safety Bot\on.png")
on=on.resize((60,25),Image.ANTIALIAS)
on=ImageTk.PhotoImage(on)
off=Image.open(r"S:\Ideas\Fire safety Bot\off.png")
off=off.resize((60,25),Image.ANTIALIAS)
off= ImageTk.PhotoImage(off)
h = Button(tk,bd=0,command=threading,bg="cornsilk2", height =16, width=70)
h.place(relx=0.9,rely=0.03,anchor=SE)

tk.mainloop() 

我不明白你为什么需要穿线。顺便说一句,线程(target=gui(…)应该是线程(target=gui,args=(…)。@acw1668我不明白。线程(target=gui(G,tk))工作正常。此外,我将使这个GUI更大,因此尽早使用线程。如果不将GUI放在线程中,其他东西也可以放在那里,但不能放在线程中。您知道
target=GUI(…)
target=GUI
之间的区别吗?第一个将在主线程中立即执行
gui()
,即使未调用
t.start()
。在执行
t.start()
之后,后者将在另一个线程中执行
gui()
。@acw1668谢谢。但是后一个
target=gui
使按钮完全消失