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

为什么当我移动Tkinter-GUI时,工作线程会冻结?

张成济
2023-03-14

我在Python3.3中有一个Tkinter GUI,带有一个进度条和一个启动另一个线程的按钮。此线程在10秒内填充进度条,并在此期间在控制台上打印0到99之间的数字
只要我不移动或调整GUI窗口的大小,它就可以正常工作。如果我删除标记行进度。步骤(1)为了使工作线程不接触进度条,因此根本不会影响GUI,即使我正在操作窗口,它也会在控制台上连续打印数字。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from tkinter import *
import tkinter.ttk as ttk
import _thread
import time

root = Tk()

def start():
    _thread.start_new_thread(thread, ())

def thread():
    for i in range(0, 100):
        time.sleep(0.1)
        progress.step(1)     #<-----
        print(i)

progress = ttk.Progressbar()
progress.pack()
button = Button(root, text="Start", command=start)
button.pack()

root.mainloop()

为什么会发生这种情况?通常会采取什么措施来避免GUI操作导致工作线程中断?

提前谢谢!

共有1个答案

越涛
2023-03-14

IIRC,那么这取决于窗口管理器。当您移动/调整窗口大小时,一些锁定窗口(和所有子元素,包括进度条)。

较新的窗口管理器,如KDE,允许程序在窗口被操作时继续呈现到其窗口中。

[编辑]大多数UI框架都不是线程安全的。Python使用的UI框架有时是免税的,因为Python具有GIL,它确保只有一个线程会更改全局状态(即widget属性)。

有几个相关的问题如何使用Tkinter多线程:

  • 与Tkinter多线程python
  • 在tkinter循环中不断访问线程
  • Tkinter:如何使用线程来防止主事件循环冻结

简而言之,你不应该在线程中做任何与用户界面相关的工作。相反,将事件发送到main循环

 类似资料:
  • 按下按钮后,我的界面冻结。我使用线程,但我不知道为什么仍然挂起。任何帮助都将不胜感激。提前谢谢

  • 我有一个Python 3。x报表创建者,其I/O绑定(由于SQL而非python),在创建报表时主窗口将“锁定”数分钟。 所需要的只是在锁定GUI时使用标准窗口操作(移动、调整大小/最小化、关闭等)(GUI上的所有其他内容都可以保持“冻结”,直到所有报告完成)。 添加20181129:换句话说,tkinter必须只控制应用程序窗口的内容,并将所有标准(外部)窗口控件的处理留给O/S。如果我能做到这

  • 我有一个简单的java gui(代码如下),由于某种原因,当显示时,当我第一次尝试移动或调整它的大小时,它会“跳”回原来的位置。所以基本上,我必须移动gui两次才能使它移动一次,因为当我第一次释放鼠标时,它就会弹回原来的位置。 我正在使用Java1.6运行GNU Linux。我正在将显示导出回我的Windows机器,并想知道它是否与X11转发有关,因为当我在Windows中运行gui时,它不显示这

  • 我是python新手,制作了一个Tkinter应用程序,当按下开始按钮时,它将执行目录中存在的所有python文件。我的GUI也有progressbar来查看当前的进度。 这是我的代码 但我的问题是,每当我按下开始按钮,GUI就会冻结,代码开始编译,完成后,GUI就会解冻,Progressbar会立即填满自己。。。 因此,我希望GUI在处理时不要冻结,并在Progressbar上显示正确的进度。

  • 我有一个工作正常的GUI类,但是我在那个GUI类中有一个按钮,应该是从另一个类打开一个新的GUI... 然而,当调用新的GUI类(newGui)时,它只是一个透明窗口。这是因为两个GUI不能同时运行吗? 我现在正试图以线程的形式打开新的GUI,但我不知道该怎么做! 公开无效运行(); 这是我的尝试,但不出所料,这没有成功。 有什么帮助吗? 谢谢

  • 在研究tkinter多线程时,我发现tkinter必须在主线程上运行(就像许多GUI框架),当一个单独的线程需要与GUI通信时,必须使用队列,而不是直接从工作线程访问小部件。 我试图学习使用队列方法,但当然最初我想看看如果我做错了会发生什么,所以我写了这段代码,它近似于Pi(π)几秒钟: 据我所知,由注释是问题。但是这个代码运行得很好。保持响应,标签和进度条都会更新。