Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-tkinter按钮冻结_Python_Tkinter - Fatal编程技术网

Python-tkinter按钮冻结

Python-tkinter按钮冻结,python,tkinter,Python,Tkinter,我在Python中冻结应用程序时遇到问题。我用tkinter库制作了一些应用程序。当我使用发送按钮时,它会调用持续3分钟的函数,并在这3分钟内冻结应用程序。。。我想查看此函数“live”中的所有日志。我不能等3分钟就拿到所有的日志 下面是我的代码示例: import tkinter as tk from tkinter import ttk from tkinter import scrolledtext import time class Frames: def main_fra

我在Python中冻结应用程序时遇到问题。我用tkinter库制作了一些应用程序。当我使用发送按钮时,它会调用持续3分钟的函数,并在这3分钟内冻结应用程序。。。我想查看此函数“live”中的所有日志。我不能等3分钟就拿到所有的日志

下面是我的代码示例:

import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext
import time


class Frames:

    def main_frame(self, win):

        # Main Frame
        main = ttk.LabelFrame(win, text="")
        main.grid(column=0, row=0, sticky="WENS", padx=10, pady=10)
        return main

    def button_frame(self, win):

        # Button Frame
        butt_frame = ttk.LabelFrame(win, text="Button")
        butt_frame.grid(column=0, row=0, sticky='NWS')

        def _send_button():
            for i in range(10):
                self.write_text_console("{0}\n".format(i))
                time.sleep(0.5)

        # Send Button
        ttk.Label(butt_frame, text="                                         ").grid(column=0, row=8)
        button = tk.Button(butt_frame, text="Send", command=_send_button, foreground='black')
        button.grid(column=0, row=13, sticky=tk.EW)

    def scrolled_text_widget(self, win):
        ttk.Label(win, text="                                         ").grid(column=0, row=1)
        ttk.Label(win, text="Console Output:").grid(column=0, row=2, sticky=tk.W)
        self.scr = scrolledtext.ScrolledText(win, width=100, height=10, wrap=tk.WORD, state="disabled")
        self.scr.grid(column=0, row=3, columnspan=5)

    def write_text_console(self, string, color="black", tag="console"):
        self.scr.configure(state='normal')
        self.scr.insert('end', string, tag)
        self.scr.tag_config(tag, foreground=color)
        self.scr.configure(state='disabled')
        self.scr.see("end")


win = tk.Tk()
win.geometry("845x300")
win.resizable(0, 0)
frames = Frames()
main = frames.main_frame(win)
frames.button_frame(main)
frames.scrolled_text_widget(main)
win.mainloop()
这个例子说明了我的问题。当你点击发送按钮时,它会将应用程序冻结5秒。但我需要在循环过程中查看日志


如何解决此问题?

Tkinter正在主线程中运行一个循环,这就是为什么当您单击按钮时,应用程序会冻结。解决方案是创建一个新线程

1-必须导入线程

import threading
2-在_send_button()函数中启动一个新线程。应该是这样的

 def _send_button():

        def click_button():
            for i in range(10):
                self.write_text_console("{0}\n".format(i))
                time.sleep(0.5)

        threading.Thread(target=click_button).start()

要冻结按钮,请在特定按钮小部件中添加
state=DISABLED

from tkinter import *

#Create an instance of tkiner frame
root= Tk()

#Define the geometry of the function
root.geometry("400x250")

Button(root, text="OK", state= DISABLED).pack(pady=20)

root.mainloop()

虽然这适用于小代码,
tkinter
是单线程的,不能在两个线程之间进行通信。我曾考虑过线程,但以前没有使用过。谢谢你的回答和链接,我可以从中了解更多!重新编写代码,使其与
win.after()
一起工作。为什么不使用
\uuuu init\uuuu
并在其中定义
win
等属性,这样它就可以在任何地方使用,而不是传递给每个方法。