从Tkinter运行线程并等待直到完成

达科夫

我有一个tkinter应用程序(作为主线程运行),在其中打开了一个新的顶级窗口-它是打印测试结果的日志窗口(该测试是使用Selenium Webdriver执行的)。该对话框也是所有测试的调用方。

因此,我想显示对话框(作为顶层,整个应用程序还有一个窗口),运行测试,等待测试完成并打印结果,然后对另一个测试单元执行相同的操作。但是我不想在测试期间冻结窗口。

我尝试使用线程,但是显然它可以那样工作。在这种情况下,直到测试完成,对话框才开始。

这是对话框窗口的代码。

class TestDialog(tkinter.Toplevel):

    def __init__(self, parent, tester, url):
        super().__init__(parent)        
        self.parent = parent
        self.webtester = tester;

        self.__initComponents()

        self.run(url)            

        self.wait_window(self)

    def __initComponents(self): 
        self.transient(self.parent)

        frame = tkinter.Frame(self)

        self._tarea = tkinter.Text(frame, state='disabled',wrap='none', width=55, height=25)

        vsb = tkinter.Scrollbar(frame, orient=tkinter.VERTICAL, command=self._tarea.yview)
        self._tarea.configure(yscrollcommand=vsb.set)


        self._tarea.grid(row=1, column=0, columnspan=4, sticky="NSEW", padx=3, pady=3)
        vsb.grid(row=1, column=4, sticky='NS',pady=3)
        frame.grid(row=0, column=0, sticky=tkinter.NSEW)

        frame.columnconfigure(0, weight=2)
        frame.rowconfigure(1, weight=1)

        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1) 
        window.rowconfigure(0, weight=1) 

        self.bind("<Escape>", self.close)

        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()

    def appendLine(self, msg):
        self._tarea['state'] = 'normal'
        self._tarea.insert("end", msg+'\n')
        self._tarea['state'] = 'disabled'

    def run(self, url):

        self.appendLine("Runneing test #1...")

        try:
            thr = threading.Thread(target=self.webtester.urlopen, args=(url,))
            thr.start() 
        except:
            pass

        thr.join()

        self.webtester.urlopen(url)

        self.appendLine("Running test #2")        
        try: 
            thr = threading.Thread(target=self.webtester.test2)
            thr.start() 
        except:
            pass          

    def close(self, event=None):
        self.parent.setBackgroundScheme(DataTreeView.S_DEFAULT)
        self.parent.focus_set()
        self.destroy()

可以通过以下方式从父窗口打开此对话框:

testDialog = TestDialog(self.parent, self._webtester, url)

感谢您的任何建议。

算了吧

为了防止GUI冻结,您需要self.run()快速结束。它需要产生一个线程,启动该线程,然后结束:

import Queue
sentinel = object()
root = tkinter.Tk()

...
def run(self, url):
    outqueue = Queue.Queue()
    thr = threading.Thread(target=self.run_tests, args=(url, outqueue))
    thr.start()
    root.after(250, self.update, outqueue)

现在,此线程运行的功能可以运行很长时间:

def run_tests(self, url, outqueue):
    outqueue.put("Running test #1...")
    self.webtester.urlopen(url)
    outqueue.put("Running test #2")        
    self.webtester.test2()
    outqueue.put(sentinel)

但是由于Tkinter希望所有GUI调用都源自单个线程,因此该生成的线程不能进行任何GUI调用。为了使其与GUI交互,您可以通过发送输出(例如状态更新消息),Queue.Queue并同时让Tkinter主线程Queue.Queue定期监视此行为(通过调用root.after):

def update(self, outqueue):
    try:
        msg = outqueue.get_nowait()
        if msg is not sentinel:
            self.appendLine(msg)
            root.after(250, self.update, outqueue)
        else:
            # By not calling root.after here, we allow update to
            # truly end
            pass
    except Queue.Empty:
        root.after(250, self.update, outqueue)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

等待方法运行,直到CCActionSequence完成

来自分类Dev

等待主线程,直到其他线程未完成!

来自分类Dev

C#等待直到所有线程完成执行

来自分类Dev

Java,等待启动线程,直到完成相等的实例

来自分类Dev

如何运行x线程数量并等待线程完成

来自分类Dev

让线程在主窗体关闭后运行,而不必等待线程完成

来自分类Dev

阻塞Tkinter接口,直到线程完成其任务

来自分类Dev

Python GUI保持冻结状态,等待线程代码完成运行

来自分类Dev

等待UI线程完成

来自分类Dev

等待事件完成(线程)

来自分类Dev

等待直到NSURLConnection sendAsynchronousRequest完成

来自分类Dev

等待IAsyncResult函数直到完成

来自分类Dev

Python线程:第二个线程等待,直到第一个线程完成

来自分类Dev

等待线程直到文件修改

来自分类Dev

等待直到线程完成,然后再执行下一步

来自分类Dev

如何等待作业,直到父作业在python中完成多线程处理?

来自分类Dev

如何在C#中等待主线程直到异步任务完成

来自分类Dev

让Exe继续直到线程完成

来自分类Dev

Spring - 如何在完成之前运行一系列线程并等待它们完成?

来自分类Dev

运行一个新线程,不要等待该线程完成

来自分类Dev

同时运行不同的线程,而无需等待其他线程完成

来自分类Dev

等待线程完成以及将来

来自分类Dev

等待线程完成 OkHttp 调用

来自分类Dev

运行音频线程会阻止触摸屏输入,直到完成

来自分类Dev

使1个线程等待线程数组完成

来自分类Dev

如何等待,直到UploadStringAsync方法完成

来自分类Dev

快速等待,直到dataTaskWithRequest完成调用返回

来自分类Dev

如何使Excel RefreshAll等待关闭直到完成?

来自分类Dev

人偶等待,直到Cloudfare重定向完成

Related 相关文章

  1. 1

    等待方法运行,直到CCActionSequence完成

  2. 2

    等待主线程,直到其他线程未完成!

  3. 3

    C#等待直到所有线程完成执行

  4. 4

    Java,等待启动线程,直到完成相等的实例

  5. 5

    如何运行x线程数量并等待线程完成

  6. 6

    让线程在主窗体关闭后运行,而不必等待线程完成

  7. 7

    阻塞Tkinter接口,直到线程完成其任务

  8. 8

    Python GUI保持冻结状态,等待线程代码完成运行

  9. 9

    等待UI线程完成

  10. 10

    等待事件完成(线程)

  11. 11

    等待直到NSURLConnection sendAsynchronousRequest完成

  12. 12

    等待IAsyncResult函数直到完成

  13. 13

    Python线程:第二个线程等待,直到第一个线程完成

  14. 14

    等待线程直到文件修改

  15. 15

    等待直到线程完成,然后再执行下一步

  16. 16

    如何等待作业,直到父作业在python中完成多线程处理?

  17. 17

    如何在C#中等待主线程直到异步任务完成

  18. 18

    让Exe继续直到线程完成

  19. 19

    Spring - 如何在完成之前运行一系列线程并等待它们完成?

  20. 20

    运行一个新线程,不要等待该线程完成

  21. 21

    同时运行不同的线程,而无需等待其他线程完成

  22. 22

    等待线程完成以及将来

  23. 23

    等待线程完成 OkHttp 调用

  24. 24

    运行音频线程会阻止触摸屏输入,直到完成

  25. 25

    使1个线程等待线程数组完成

  26. 26

    如何等待,直到UploadStringAsync方法完成

  27. 27

    快速等待,直到dataTaskWithRequest完成调用返回

  28. 28

    如何使Excel RefreshAll等待关闭直到完成?

  29. 29

    人偶等待,直到Cloudfare重定向完成

热门标签

归档