【问题标题】:Tkinter Frozen Screen when start button is clicked单击开始按钮时的 Tkinter 冻结屏幕
【发布时间】:2021-11-28 12:23:30
【问题描述】:

我正在尝试编写一个带有开始和停止按钮的 tkinter 程序。对于开始和停止按钮,我从不同的 .py 文件中导入了两个不同的函数。当我点击开始按钮时,tkinter 冻结,我的光标一直在“处理”并且不允许我点击停止按钮。

我的 tkinter 程序如下:

import tkinter as tk
from start import hello
from stop import quitprog

class Page(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
    def show(self):
        self.lift()

class Page1(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="Collecting Data Now...")
       label.pack(side="top", fill="both", expand=True)

class Page2(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="Analyzing Data Now...")
       label.pack(side="top", fill="both", expand=True)


class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        p1 = Page1(self)
        p2 = Page2(self)

        buttonframe = tk.Frame(self)
        container = tk.Frame(self)
        buttonframe.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)


        b1 = tk.Button(buttonframe, text="start", command=hello)
        b2 = tk.Button(buttonframe, text="stop", command=quitprog)

        b1.pack(side="left")
        b2.pack(side="left")

        p1.show()

if __name__ == "__main__":
    root = tk.Tk()
    main = MainView(root)
    main.pack(side="top", fill="both", expand=True)
    root.wm_geometry("400x400")
    root.mainloop()

我的 start.py 如下:

import time
def hello():
    for i in range(20):
        print("hello world")
        time.sleep(1)

我的 stop.py:

import sys
def quitprog():
    sys.exit()

我的冻结窗口:

loading/processing cursor image

请告诉我如何解决这个问题。

编辑:我实际上是在调用实时 twitter 流,而不是 start.py 程序,它没有使用 .sleep()。取而代之的是,推特数据的持续流动,导致程序冻结。有什么解决办法吗?

【问题讨论】:

  • time.sleep(1) 确实会阻止您的代码一秒钟,然后您调用它 20 次,这将是冻结事件循环的 20 秒。你有什么期待?
  • 我实际上是在调用一个实时 Twitter 流,而不是 start.py 程序,它没有使用 .sleep()。取而代之的是,推特数据源源不断。每当我单击开始按钮时,程序就会冻结并且不允许我单击停止按钮。有什么解决办法吗?
  • 你需要使用另一个thread

标签: python-3.x tkinter


【解决方案1】:

您需要使用多线程。最简单的使用(在我看来)是标准库multiprocessing 模块:

import multiprocessing

...


class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        p1 = Page1(self)
        p2 = Page2(self)

        buttonframe = tk.Frame(self)
        container = tk.Frame(self)
        buttonframe.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)


        b1 = tk.Button(buttonframe, text="start", command=self.hello)
        b2 = tk.Button(buttonframe, text="stop", command=quitprog)

        b1.pack(side="left")
        b2.pack(side="left")

        p1.show()
    
    def hello(self, *args):
        p = multiprocessing.Process(target=hello)
        p.start()

quitprog 不需要在单独的进程中运行,也不能,因为那样sys.exit 不会终止你的程序。 我只包含了MainView 类代码 - 确保添加其余部分!

【讨论】:

  • p = multiprocessing.Process(hello) 行有语法错误,应改为p = multiprocessing.Process(target=hello)。同样在其他进程中运行quitprog() 无法终止当前进程。
  • @acw1668 哎呀,感谢您的提示,已修复。
猜你喜欢
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 2021-06-24
  • 2021-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多