相关疑难解决方法(0)

Tkinter:如何使用线程来防止主事件循环"冻结"

我有一个小的GUI测试,带有"开始"按钮和进度条.期望的行为是:

  • 单击开始
  • 进度条振荡5秒
  • 进度条停止

观察到的行为是"开始"按钮冻结5秒钟,然后显示进度条(无振荡).

到目前为止,这是我的代码:

class GUI:
    def __init__(self, master):
        self.master = master
        self.test_button = Button(self.master, command=self.tb_click)
        self.test_button.configure(
            text="Start", background="Grey",
            padx=50
            )
        self.test_button.pack(side=TOP)

    def progress(self):
        self.prog_bar = ttk.Progressbar(
            self.master, orient="horizontal",
            length=200, mode="indeterminate"
            )
        self.prog_bar.pack(side=TOP)

    def tb_click(self):
        self.progress()
        self.prog_bar.start()
        # Simulate long running process
        t = threading.Thread(target=time.sleep, args=(5,))
        t.start()
        t.join()
        self.prog_bar.stop()

root = Tk()
root.title("Test Button")
main_ui = GUI(root)
root.mainloop()
Run Code Online (Sandbox Code Playgroud)

基于从布赖恩奥克利的信息在这里,我明白,我需要使用线程.我尝试创建一个线程,但我猜测,因为线程是从主线程中启动的,所以没有用.

我有想法放置在不同的类中的逻辑部分,以及从该类,类似于由A.罗达斯示例代码内实例化GUI 这里.

我的问题:

我无法弄清楚如何编码它,以便这个命令:

self.test_button = Button(self.master, command=self.tb_click)
Run Code Online (Sandbox Code Playgroud)

调用位于另一个类中的函数.这是一件坏事还是可能?我如何创建一个可以处理self.tb_click的第二类?我试着跟随A. Rodas的示例代码,它的工作非常精彩.但是我无法弄清楚如何在触发动作的Button小部件的情况下实现他的解决方案.

如果我应该在单个GUI类中处理线程,那么如何创建一个不干扰主线程的线程呢?

python multithreading tkinter event-loop progress-bar

43
推荐指数
4
解决办法
7万
查看次数

Python Tkinter Label每10秒重绘一次

我有以下Python Tkinter代码,它每10秒重绘一次标签.我的问题是,对我而言似乎是在旧标签上一遍又一遍地绘制新标签.因此,最终,几个小时后将有数百个绘图重叠(至少从我的理解).这会占用更多内存还是会导致问题?

import Tkinter as tk
import threading

def Draw():
    frame=tk.Frame(root,width=100,height=100,relief='solid',bd=1)
    frame.place(x=10,y=10)
    text=tk.Label(frame,text='HELLO')
    text.pack()

def Refresher():
    print 'refreshing'
    Draw()
    threading.Timer(10, Refresher).start()

root=tk.Tk()
Refresher()
root.mainloop()
Run Code Online (Sandbox Code Playgroud)

在我的例子中,我只使用一个标签.我知道我可以使用textvariable更新标签的文本甚至text.config.但实际上做的是刷新标签网格(如表格)+按钮和内容以匹配可用的最新数据.

从我的初学者的理解,如果我把这个Draw()函数写成类,我可以frame通过使用frame.destroy每当我执行Refresher函数来销毁它.但是我目前拥有的代码是在没有类的函数中编写的(我不希望将整个代码重写为类).

我能想到的另一个选择是frameDraw()全局和使用中声明frame.destroy()(我不愿意这样做,因为如果我有太多帧(这样做),这可能会导致名称冲突)

如果对旧图纸进行透支不会导致任何问题(除了我看不到旧图纸),我可以忍受.

这些都只是我初学者的想法.我应该在重绘更新的帧之前销毁帧吗?如果是这样,如果代码结构就像我的示例代码一样,我应该以什么方式销毁它?或透支旧标签是好的?

编辑

有人提到python tkinter不是线程安全的,我的代码可能会随机失败.

我实际上把这个链接作为参考使用threading作为我的解决方案,我没有找到任何关于该帖子中的线程安全性.

我想知道我不应该使用的一般情况是threading什么,我可以使用的一般情况是什么threading

python multithreading label tkinter

4
推荐指数
2
解决办法
1万
查看次数

如何使用 tkinter 在图像上绘制坐标系?

我想显示一个图像并在它上面绘制一个坐标系(x 轴,y 轴)。我可以显示图像

img = ImageTk.PhotoImage(Image.open(path).resize((400,400),Image.ANTIALIAS))
panel = tk.Label(root,image = img, width = 400, height = 400s)
panel.pack(size= "bottom", fill = "both", expand = "yes")
panel.place(rely = 073, rely = 0.5s) 
Run Code Online (Sandbox Code Playgroud)

我也可以为 x 轴 / y 轴画一条线(如果你知道一种绘制闪光而不是线的方法会更好)

canvas = Canvas(root)
canvas.create_line(x0,y0,x1,y1)
canvas.pack()
Run Code Online (Sandbox Code Playgroud)

我不能做的是将这条线放在图像的顶部。我尝试使用 canvas.place(),但是当我把它放在图像的顶部时,我再也看不到图像了。有没有办法使画布透明?或者我还能做什么?我是 Tkinter 的新手。

谢谢。

编辑:显然不可能在 tkinter python 中制作透明画布透明画布

但是我可以在画布中添加背景图像然后绘制线条,以便我可以看到两者吗?

python canvas tkinter

2
推荐指数
1
解决办法
2791
查看次数