我有一个小的GUI测试,带有"开始"按钮和进度条.期望的行为是:
观察到的行为是"开始"按钮冻结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 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函数来销毁它.但是我目前拥有的代码是在没有类的函数中编写的(我不希望将整个代码重写为类).
我能想到的另一个选择是frame在Draw()全局和使用中声明frame.destroy()(我不愿意这样做,因为如果我有太多帧(这样做),这可能会导致名称冲突)
如果对旧图纸进行透支不会导致任何问题(除了我看不到旧图纸),我可以忍受.
这些都只是我初学者的想法.我应该在重绘更新的帧之前销毁帧吗?如果是这样,如果代码结构就像我的示例代码一样,我应该以什么方式销毁它?或透支旧标签是好的?
编辑
有人提到python tkinter不是线程安全的,我的代码可能会随机失败.
我实际上把这个链接作为参考使用threading作为我的解决方案,我没有找到任何关于该帖子中的线程安全性.
我想知道我不应该使用的一般情况是threading什么,我可以使用的一般情况是什么threading?
我想显示一个图像并在它上面绘制一个坐标系(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 中制作透明画布透明画布
但是我可以在画布中添加背景图像然后绘制线条,以便我可以看到两者吗?