【问题标题】:tkinter python button run in background commandtkinter python按钮在后台命令中运行
【发布时间】:2012-02-22 16:10:44
【问题描述】:

我在纠结 Tkinter 和 Python。我有一个带有几个按钮的基本 gui,一个按钮消失并执行需要一些时间的操作,这是可变的。问题是当我点击这个按钮时,我的整个 gui 被锁定/没有正确显示 - 我猜是因为它试图做这些需要一些时间的事情并且它阻塞了 gui。

我已经研究过线程和队列,但我无法弄清楚。我想我需要在一个线程上触发我的查找方法,然后在结果返回时将结果排队并在返回时更新列表框?

如果这对我使用线程的方式有影响,我就在 Windows 上。

亲切的问候

大卫

基本代码如下。

class Search:

        def __init__(self, master):

            self.seeds = []

            frame = Frame(master, width=700, height=500)
            frame.pack_propagate(0)
            frame.pack(expand=YES, fill=BOTH)

            #
            # Search results
            #
            l2 = Label(frame, text="results")
            l2.pack(anchor=W)
            self.resultfield = Listbox(frame, selectmode=BROWSE)
            self.resultfield.grid(row=3, column=1, sticky=N+W+S+E, columnspan=3)
            self.resultfield.pack(fill=BOTH)

            frame1 = Frame(frame)
            frame1.pack()


            # Button to action the search
            self.getSearchbut = Button(frame1, text="Do Search", command=self.getSearch)
            self.getSearchbut.grid(row=1, column=2)
            self.getSearchbut.pack()

        def getSearch(self):


            sa = SearchApi(self.seeds)

            results = sa.lookup(self)


            for result in results:
                self.resultfield.insert(END, user)

        def putCSV(self):
            print "put the csv files"

class SearchApi: 

        def __init__(self, seeds):
            self.seeds = seeds

        def lookup(self):
            results = []
                # I do something here that takes a while
                return results




if __name__ == "__main__":

    root = Tk()
    root.title("Search")

    app = Search(root)

    root.mainloop()

【问题讨论】:

  • 您能发布您尝试过的线程代码吗?根据我的经验,一旦你关闭线程,问题通常集中在没有对线程进行编程以保持不变或线程本身被挂起并且无法放弃并将控制权交还给图形用户界面。
  • 这无论如何都与 TKinter 无关...

标签: python tkinter


【解决方案1】:

使用线程很简单,真的。您所要做的就是导入 Thread 类:

from threading import Thread

并将 getSearch 函数更改为如下所示:

def getSearch(self):
    t= Thread(target=self.search)#this should work, in case it doesn't, try "t= Thread(target=Search.getSearch,args=[self])" instead.
    t.start()

def search(self):
    sa = SearchApi(self.seeds)
    results = sa.lookup(self)
    for result in results:
        self.resultfield.insert(END, user)

这应该是你需要做的,因为我很确定 Tkinter 是线程安全的。如果不是,您必须创建一个线程,将另一个线程的结果插入到文本小部件中。

另外,这是 Python。不管你是否在 Windows 上:D

【讨论】:

    【解决方案2】:

    直到今天我都遇到了同样的问题! 您的问题是 Tkinter 的主循环干扰了您的任务循环。 我不得不从我的程序中去掉所有的类并且只使用函数。您使用的按钮将切换一个变量,然后启动循环任务。

    然后解决方案很简单,经过大约一周的查找(这是我的代码的精简版):

       scnBtn = Button(Frame, text="Update", command=readIt)
       scnBtn.pack()
    
    
    def readIt(): ## this is the variable the button changes
        global read
    
        read = 1
        TK.after(0, readFile) ##this is how you make sure the GUI doesn't freeze up
    
    def readFile(): ## this is the task you want the button to do
        global read
    
        if read == 1:
    
            "your task"
    
            if "task is over"
    
                read = 0
    
        if read == 1:
            TK.after(0, readFile) ## this will keep the task going until its done.
    

    希望这有帮助!

    【讨论】:

      猜你喜欢
      • 2019-05-10
      • 1970-01-01
      • 2023-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-23
      • 2014-01-10
      • 2011-04-11
      相关资源
      最近更新 更多