<small id='fvEq1'></small><noframes id='fvEq1'>

    <tfoot id='fvEq1'></tfoot>
  1. <i id='fvEq1'><tr id='fvEq1'><dt id='fvEq1'><q id='fvEq1'><span id='fvEq1'><b id='fvEq1'><form id='fvEq1'><ins id='fvEq1'></ins><ul id='fvEq1'></ul><sub id='fvEq1'></sub></form><legend id='fvEq1'></legend><bdo id='fvEq1'><pre id='fvEq1'><center id='fvEq1'></center></pre></bdo></b><th id='fvEq1'></th></span></q></dt></tr></i><div id='fvEq1'><tfoot id='fvEq1'></tfoot><dl id='fvEq1'><fieldset id='fvEq1'></fieldset></dl></div>
    <legend id='fvEq1'><style id='fvEq1'><dir id='fvEq1'><q id='fvEq1'></q></dir></style></legend>
      <bdo id='fvEq1'></bdo><ul id='fvEq1'></ul>

    1. 将队列与 tkinter(和线程)一起使用

      时间:2023-09-29

        • <i id='oe1tk'><tr id='oe1tk'><dt id='oe1tk'><q id='oe1tk'><span id='oe1tk'><b id='oe1tk'><form id='oe1tk'><ins id='oe1tk'></ins><ul id='oe1tk'></ul><sub id='oe1tk'></sub></form><legend id='oe1tk'></legend><bdo id='oe1tk'><pre id='oe1tk'><center id='oe1tk'></center></pre></bdo></b><th id='oe1tk'></th></span></q></dt></tr></i><div id='oe1tk'><tfoot id='oe1tk'></tfoot><dl id='oe1tk'><fieldset id='oe1tk'></fieldset></dl></div>

          • <bdo id='oe1tk'></bdo><ul id='oe1tk'></ul>

              <small id='oe1tk'></small><noframes id='oe1tk'>

              <legend id='oe1tk'><style id='oe1tk'><dir id='oe1tk'><q id='oe1tk'></q></dir></style></legend>

            1. <tfoot id='oe1tk'></tfoot>

                  <tbody id='oe1tk'></tbody>
                本文介绍了将队列与 tkinter(和线程)一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                我在 Python 3 中有一个脚本,我正在尝试使用 tkinter 为它制作一个 GUI.

                I have a script in Python 3 and I'm trying to make a GUI for it using tkinter.

                这是一个完整的工作代码示例:

                Here is a complete example of working code:

                #!/usr/bin/python
                # coding: utf-8
                
                import pickle
                import openpyxl
                
                from tkinter import *
                import threading
                import queue
                
                
                class Worker():
                
                    def __init__(self):
                        self.one_name_list = []
                        self.dic = {}
                
                        self.root = Tk()
                        self.root.title("GUI Python")
                        self.root.geometry("820x350")
                
                        self.thread_queue = queue.Queue()
                
                        self.btn1 = Button(text="start counting", width = '20', height = '1', background = "#555", foreground = "#ccc", command=self.start_working)
                        self.btn1.grid(row=0, column=0, columnspan=2, ipadx=10, ipady=6, padx=5, pady=5, sticky=N)
                        self.btn2 = Button(text="stop counting", width = '20', height = '1', background = "#555", foreground = "#ccc", command=self.stop_running)
                        self.btn2.grid(row=1, column=0, columnspan=2, ipadx=10, ipady=6, padx=5, pady=5, sticky=N)
                        self.btn5 = Button(text="clear window", width = '10', height = '1', background = "#555", foreground = "#ccc", command=self.tex_clear)
                        self.btn5.grid(row=3, column=0, columnspan=2, ipadx=10, ipady=6, padx=5, pady=5, sticky=N)
                
                        self.tex = Text(self.root, width = 72, height = 20, font="Verdana 10", wrap=WORD)
                        self.tex.grid(row=0, column=2, rowspan=4, ipadx=10, ipady=6, padx=5, pady=5)
                
                        self.S = Scrollbar(self.root, orient="vertical", command=self.tex.yview)
                        self.S.grid(row=0, column=4, rowspan=4,  ipady=143, pady=5, sticky=W)
                        self.tex.config(yscrollcommand=self.S.set)
                
                        self.root.after(100, self.listen_for_result)
                
                        self.root.mainloop()
                
                
                    def read_from_pickle_file(self, filename):
                        """ Reads python object from pickle file. """
                
                        # with open(filename, 'rb') as handle:
                        #     obj = pickle.load(handle)
                
                        self.thread_queue.put('Got list file.
                ')
                        return True
                
                    def get_boxes(self, xlsx_filename, txt_filename=None):
                
                        pass # does some job
                        self.thread_queue.put('Got boxes list.
                ')
                
                    def tex_clear(self):
                
                        self.tex.delete('1.0', END)
                        self.tex.see("end")
                
                    def stop_running(self):
                
                        pass # stops somehow
                
                    def _print(self, text):
                        self.tex.insert(END, text)
                        self.tex.see("end")
                
                    def start_working(self):
                
                        t = threading.Thread(target=self.start_working_2)
                        t.start()
                
                    def start_working_2(self):
                
                        self.one_name_list = self.read_from_pickle_file('1.pickle')
                        self.root.after(100, self.listen_for_result)
                
                        self.boxes_list = self.get_boxes('1.xlsx')
                        self.root.after(100, self.listen_for_result)
                
                        self.thread_queue.put('Getting files
                ')
                        self.root.after(100, self.listen_for_result)
                
                    def listen_for_result(self):
                        """ Check if there is something in the queue. """
                
                        try:
                            self.res = self.thread_queue.get(0)
                            self._print(self.res)
                        except queue.Empty:
                            self.root.after(100, self.listen_for_result)
                
                
                if __name__ == '__main__':
                
                    se = Worker()
                

                您可以运行它并查看工作窗口.

                You can run it and see the working window.

                我有几个问题.

                这个 GUI 的想法是有 3 个按钮 - 开始运行、停止运行和清除文本窗口.文本窗口 - 应该替代控制台 - 所有消息都应该在文本窗口中打印,而不是控制台.

                The idea of this GUI - is that there are 3 buttons - start running, stop running, and clear text window. Text window - should be a substitute for a console - all messages should be printed in text window, instead of console.

                现在我使用队列来打印消息.但我想我用错了——因为每次放东西后我都需要手动检查队列.

                For now I'm using queue to print messages. But I guess I'm using it in a wrong way - because I need manually to check the queue every time after I put something there.

                所以,问题:

                1. 有没有办法自动检查队列一直 - 并立即将进入队列的所有内容打印到文本窗口,无论它来自哪个线程?(每次放东西后我都可以忍受检查队列,但是会有几个函数无法预测他们将发送东西多少次到队列中 - 所以我将无法检查队列是否未知次数.)

                1. Is there a way to check queue autamatically all the time - and instantly print to text window everything which gets to the queue, no matter from which thread it came there? (I can put up with checking queue every time after I put something there, but there will be couple of functions where it is impossible to predict how many times they will send something to queue - so I will not be able to check queue for unknown number of times.)

                如果您回答第一个问题,我将考虑已回答的问题.
                其他问题是可选的.

                I will consider the question answered if you answer the first question.
                Other questions are optional.

                我是否正确启动了 GUI?它应该在 __init__() 还是其他地方?

                Am I starting the GUI correctly? Should it be in the __init__() or somewhere else?

                如何隐藏控制台窗口?(尝试重命名为 .pyw - 控制台和 GUI 均未出现.尝试将 self.root.withdraw() 放在 self.root = Tk() 之后 - 结果:控制台出现了,GUI - 没有.)

                how to hide the console window? (tried renaming to .pyw - neither console, nor GUI showed up. Tried putting self.root.withdraw() after self.root = Tk() - the result: console showed up, GUI - not.)

                这段代码中是否有任何笨拙或愚蠢的地方(GUI、线程、队列)?我使用几本手册编写了这段代码,所以我可能会误解其中的部分或全部,并以错误的方式进行操作.

                Is there any clumsy or stupid places in this code (GUI, threading, queue)? I wrote this code using several manuals, so I could be misunderstanding some or all of them and do it in a wrong way.

                推荐答案

                发现很简单:在这个函数中

                It figured out to be quite simple: in this function

                def listen_for_result(self):
                        """ Check if there is something in the queue. """
                
                        try:
                            self.res = self.thread_queue.get(0)
                            self._print(self.res)
                        except queue.Empty:
                            self.root.after(100, self.listen_for_result)
                

                应该再添加一个对自身的调用 - 即使在成功打印之后也是如此.在此之后 - 我可以从任何地方将文本发送到队列,并且在将文本发送到队列后立即打印它而无需调用此函数.

                should be added one more call to itself - even after successfull printing. After this - I can send text to queue from anywhere and it will be printed without calling this function right after sending text to queue.

                def listen_for_result(self):
                        """ Check if there is something in the queue. """
                
                        try:
                            self.res = self.thread_queue.get(0)
                            self._print(self.res)
                            self.root.after(100, self.listen_for_result)
                        except queue.Empty:
                            self.root.after(100, self.listen_for_result)
                

                那么现在

                self.thread_queue.put('Getting files
                ')
                

                可以在任何线程中使用.而不是

                can be used in any thread. Instead of

                 self.thread_queue.put('Getting files
                ')
                 self.root.after(100, self.listen_for_result)
                

                像以前一样双线.

                这篇关于将队列与 tkinter(和线程)一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                上一篇:Python如何用信号杀死队列中阻塞的线程? 下一篇:向 Python 中的所有线程发送单向消息

                相关文章

                <i id='vSFbw'><tr id='vSFbw'><dt id='vSFbw'><q id='vSFbw'><span id='vSFbw'><b id='vSFbw'><form id='vSFbw'><ins id='vSFbw'></ins><ul id='vSFbw'></ul><sub id='vSFbw'></sub></form><legend id='vSFbw'></legend><bdo id='vSFbw'><pre id='vSFbw'><center id='vSFbw'></center></pre></bdo></b><th id='vSFbw'></th></span></q></dt></tr></i><div id='vSFbw'><tfoot id='vSFbw'></tfoot><dl id='vSFbw'><fieldset id='vSFbw'></fieldset></dl></div>

                  <bdo id='vSFbw'></bdo><ul id='vSFbw'></ul>
                1. <legend id='vSFbw'><style id='vSFbw'><dir id='vSFbw'><q id='vSFbw'></q></dir></style></legend>

                  <small id='vSFbw'></small><noframes id='vSFbw'>

                    <tfoot id='vSFbw'></tfoot>