Tkinter python多线程(避免“无响应”)

时间:2017-04-14 06:16:30

标签: python tkinter

我正在尝试使用tkinter编写Python GUI程序。

我想制作两个帖子。一个运行main_form函数以保持tkinter保持更新和循环(避免“不响应”)。

另一方面,当单击button1(btn1)时,make函数sci_thread()开始运行并启动执行带有长时间代码的main_scikit的thread2。

但是tkinter保持不响应。

以下是我的代码:

import threading

class class_one:
    def main_scikit(seft):
        ######
        code_take_loooong_time
        ######
    def save(seft):
        pass

    def main_form(seft):
        root = Tk(  )
        root.minsize(width=300, height=500)
        ent1 = Entry(width=30)
        ent1.grid(row=0,column=1,padx = 10,pady=5)
        bnt1 = Button(root,text = "Start",command=lambda : seft.sci_thread())
        bnt1.grid(row=5,column=0,padx = 10) 

        root.update() 
        root.mainloop()

    def sci_thread(seft):
        maincal = threading.Thread(2,seft.main_scikit())
        maincal.start()

co = class_one()
mainfz = threading.Thread(1,co.main_form());
mainfz.start() 

1 个答案:

答案 0 :(得分:1)

您的应用没有响应,因为您的目标参数在声明时执行,其结果作为目标传递。而且,很明显,因为在GUI的线程中执行code_take_loooong_time时,GUI没有响应。处理它 - 摆脱多余的括号。

试试这个代码段:

import threading

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk


class class_one:
    def main_scikit(self):
        ######
        # code_take_loooong_time
        # same as sleep
        threading.Event().wait(5)
        # some print
        self.print_active_threads_count()

        ######
    def save(self):
        pass

    def main_form(self):

        self.root = tk.Tk()
        self.root.minsize(width=300, height=500)
        self.ent1 = tk.Entry(self.root, width=30)
        self.ent1.grid(row=0, column=1, padx=10, pady=5)
        self.bnt1 = tk.Button(self.root, text="Start", command=self.sci_thread)
        self.bnt1.grid(row=5, column=0, padx=10)

        self.root.update()
        self.root.mainloop()

    def sci_thread(self):
        maincal = threading.Thread(target=self.main_scikit)
        maincal.start()

    def print_active_threads_count(self):
        msg = 'Active threads: %d ' % threading.active_count()

        self.ent1.delete(0, 'end')
        self.ent1.insert(0, msg)
        print(msg)


co = class_one()
mainfz = threading.Thread(target=co.main_form)
mainfz.start() 

链接:

P.S: 另外,当你启动tkinter应用程序不在主线程时要小心,因为tkinter期望(通常)mainloop可能是最外层循环,并且所有Tcl命令都是从同一个线程调用的线。因此,even if you just trying to quit GUI可能存在许多同步问题! 总之,也许thisthat会给你一些新的想法。