【问题标题】:Why does the worker-thread freeze while I am moving the Tkinter-GUI?为什么在我移动 Tkinter-GUI 时工作线程会冻结?
【发布时间】:2014-09-14 20:16:33
【问题描述】:

我在 Python 3.3 中有一个 Tkinter-GUI,带有一个进度条和一个启动另一个线程的按钮。此线程在 10 秒内填充进度条,并在此期间在控制台上打印 0 到 99 之间的数字。
只要我不移动或调整 GUI 窗口的大小,它就可以正常工作。如果我删除标记的行 progress.step(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 操作导致工作线程中断?

提前致谢!

【问题讨论】:

  • 它在 Linux Mint 16 上正常工作。
  • 你使用的是哪个窗口管理器?
  • 你为什么使用_thread.start_new_thread()?请改用threading.Thread
  • tkinter 的设计目的不是为了能够从创建小部件的线程以外的任何线程调用小部件方法。它可能有效,但可能无效。
  • 好的。因此,对于 Windows7+Python+Tkinter,我别无选择,只能解决这个令人不快的问题。谢谢你的帮助! (我马上试试threading.Thread)

标签: python multithreading python-3.x tkinter freeze


【解决方案1】:

IIRC,那么这取决于窗口管理器。在您移动/调整窗口大小时,有些会锁定窗口(以及所有子窗口,包括您的进度条)。

较新的窗口管理器(如 KDE)允许程序在窗口被操作时继续渲染到其窗口中。

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

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

简而言之,您不应该在线程中执行任何与 UI 相关的工作。而是将事件发送到mainloop

【讨论】:

  • 啊,该死。我正在使用 Windows 7 ...所以我想我必须在这个操作系统上解决 Python+Tkinter 的问题?看起来很奇怪,因为 Windows 确实能够在操作 GUI 的同时渲染事物并在后台工作。如果我将 WMP 移到屏幕上,音乐不会停止。您知道其他 GUI 库是否也会发生此错误吗? (顺便说一句,我知道 WMP 在 Python 中不是 writton!;-))
  • :-/ 我同意它原则上应该在 Windows 上工作。
  • 嗯。我的代码是否违反了任何 Python 程序员的约定?有什么我想不到的吗?你会用不同的方式编码吗? (我自己并不是最有经验的程序员。)
  • 我只是设法将 GUI 放入一个从属线程本身,但这并没有改变任何东西。
猜你喜欢
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 2015-11-21
相关资源
最近更新 更多