当前位置: 首页 > 知识库问答 >
问题:

关闭时出现tkinter和线程错误的Python应用程序

扶隐水
2023-03-14

我写这个软件的一个项目作业,但我有麻烦与混合线程和tkinter。下面的部分基本上和预期的一样工作,但是当我关闭它(在Python shell中启动它之后)时,窗口显示一个错误:“Python停止工作”。

import threading
import time
import tkinter
import tkinter.ttk

class BTClient:
    def __init__(self, master):
        self.root = master
        self.root.bind("<Destroy>", self.on_destroy)

        self.t = threading.Thread(target=self.update)
        self.running = False

    def on_destroy(self, event):
        self.running = False

    def run_thread(self):
        self.running = True
        self.t.start()

    def update(self):
        while self.running:
            print("Update.")
            time.sleep(1)

def main(args):
    root = tkinter.Tk()
    client = BTClient(root)
    client.run_thread()
    root.mainloop()

if __name__ == "__main__":
    import sys
    main(sys.argv)

我怎样才能解决这个问题?是不是我现在使用的设计造成的?我应该改变它吗?

编辑1:当我删除self时。root\uuuu init\uuuu声明,并且只使用master引用问题已经解决,但是我需要有对GUI对象的引用,首先要构建GUI,还要从GUI对象获取输入,所以我不知道如何解决这个问题。也许将对象作为参数传递给可能需要它们的所有对象?

共有2个答案

姚培
2023-03-14

所以我在root.mainloop()后面添加了一行client.t.join(),这解决了问题,尽管我真的不知道为什么。我认为这是因为python在其他线程中仍然有对tkinter对象的引用时正在销毁它们,所以等待它们关闭就解决了这个问题。谢谢。

蒙华翰
2023-03-14

如果没有看到你的实际代码,很难确切地知道发生了什么,但是我会让你的线程方法成为BTClient之外的一个函数,并且将线程移到客户端之外,并在主循环之后添加对thread.join()的调用您的线程在BTClient被GC删除之前完成清理

def update():
    import time
    while thread._keep_alive:
        time.sleep(1)
        print("thread running")

thread = threading.Thread(target=update)
thread._keep_alive = True
thread.start()

在最后

thread._keep_alive = False
thread.join()
 类似资料:
  • 问题内容: 我有一个Python程序,当我使用退出应用程序时 ,脚本不会关闭。我的过程仍显示在运行的过程中。 为什么python线程不能关闭? 问题答案: 您需要将该线程设为守护程序线程。为此,请在调用线程的init之后添加以下行 当只有守护程序线程处于活动状态时,程序将退出,主线程当然是非守护程序的

  • 当我连续发布数据时,我会在C#应用程序上得到发布超时错误,一旦我重新启动应用程序,它会工作几个小时。[注意:由于php需要时间完成任务,所以新的请求都在等待中,它创建队列,等待时间超过2分钟,im出现超时错误]。 我们的两台服务器都使用了最大50%的CPU和RAM使用量 我检查了两个C#代码和PHP代码都工作良好,没有任何问题或bug 提前致谢哥们儿:)

  • 我正在使用在线程上运行的 SurfaceView 类中的画布。SurfaceView 由 Activity (setContentView(surfaceview)) 调用。当屏幕关闭时,它会通过一个 pause() 方法关闭所有循环变量等。 奇怪的是:虽然在我的平板电脑(Android 4.4.2)线程暂停和恢复正确(线程重新开始),但是在我的手机(Android 4.2.2)和其他人的手机(C

  • null 脚本'C:\src\flutter\packages\flutter_tools\gradle\flutter.gradle'行:838 出了什么问题: 任务“:app:CompileFlutterBuildreLease”执行失败。 null null 应用程序:Build.Gradle

  • 我听说Python中的线程不容易处理,而且它们与tkinter的关系更加复杂。 我有以下问题。我有两个类,一个用于GUI,另一个用于无限进程。首先,我启动GUI类,然后启动无限进程类。我希望当您关闭GUI时,它也会完成无限过程,程序也会结束。 代码的简化版本如下: 单击关闭按钮(右上角)时,控制台中会出现以下错误: 我不知道为什么会这样,也不知道这意味着什么。

  • 我正在使用Python中的wget下载一个文件,代码如下: 该文件已下载并正确保存在给定文件夹中,但进程仍在运行。我尝试了但这也不起作用。请告知。 谢谢