我正在尝试构建一个简单的程序来提醒我在使用计算机时休息一下。我对python有一个合理的理解,但以前从未玩过GUI编程或线程,所以以下内容实际上是从stackoverflow复制/粘贴:
import threading
import time
import Tkinter
class RepeatEvery(threading.Thread):
def __init__(self, interval, func, *args, **kwargs):
threading.Thread.__init__(self)
self.interval = interval # seconds between calls
self.func = func # function to call
self.args = args # optional positional argument(s) for call
self.kwargs = kwargs # optional keyword argument(s) for call
self.runable = True
def run(self):
while self.runable:
self.func(*self.args, **self.kwargs)
time.sleep(self.interval)
def stop(self):
self.runable = False
def microbreak():
root = Tkinter.Tk()
Tkinter.Frame(root, width=250, height=100).pack()
Tkinter.Label(root, text='Hello').place(x=10, y=10)
threading.Timer(3.0, root.destroy).start()
root.mainloop()
return()
thread = RepeatEvery(6, microbreak)
thread.start()
这给了我第一次休息通知,但在给我第二次休息通知之前就失败了。
Tcl_AsyncDelete:错误线程删除的异步处理程序
fish:作业1,“python Documents / python / timer / timer.py”终止 信号SIGABRT(中止)
有什么想法吗?我很乐意使用除了tkinter以外的其他东西来代替gui-stuff或其他东西来实现时间的东西。
根据以下答案,我的新工作脚本如下:
import Tkinter as Tk
import time
class Window:
def __init__(self):
self.root = None
self.hide = 10 #minutes
self.show = 10 #seconds
def close(self):
self.root.destroy()
return
def new(self):
self.root = Tk.Tk()
self.root.overrideredirect(True)
self.root.geometry("{0}x{1}+0+0".format(self.root.winfo_screenwidth(), self.root.winfo_screenheight()))
self.root.configure(bg='black')
Tk.Label(self.root, text='Hello', fg='white', bg='black', font=('Helvetica', 30)).place(anchor='center', relx=0.5, rely=0.5)
#Tk.Button(text = 'click to end', command = self.close).pack()
self.root.after(self.show*1000, self.loop)
def loop(self):
if self.root:
self.root.destroy()
time.sleep(self.hide*60)
self.new()
self.root.mainloop()
return
Window().loop()
答案 0 :(得分:5)
我认为没有线程会更容易实现这一点,Tkinter
没有很好地集成。相反,您可以使用after
和after_idle
方法来安排在特定超时后运行的回调。您可以创建一个显示窗口的方法并将其计划为隐藏窗口,另一个方法隐藏窗口并安排窗口显示。然后他们会在一个无限循环中互相称呼:
import Tkinter
class Reminder(object):
def __init__(self, show_interval=3, hide_interval=6):
self.hide_int = hide_interval # In seconds
self.show_int = show_interval # In seconds
self.root = Tkinter.Tk()
Tkinter.Frame(self.root, width=250, height=100).pack()
Tkinter.Label(self.root, text='Hello').place(x=10, y=10)
self.root.after_idle(self.show) # Schedules self.show() to be called when the mainloop starts
def hide(self):
self.root.withdraw() # Hide the window
self.root.after(1000 * self.hide_int, self.show) # Schedule self.show() in hide_int seconds
def show(self):
self.root.deiconify() # Show the window
self.root.after(1000 * self.show_int, self.hide) # Schedule self.hide in show_int seconds
def start(self):
self.root.mainloop()
if __name__ == "__main__":
r = Reminder()
r.start()
答案 1 :(得分:2)
我同意dano。我认为我也会做出贡献,因为我的方式比dano的方式要小一些,但是当窗口可见时,它会花费时间。希望这有助于@vorpal!
import Tkinter
import time
root = Tkinter.Tk()
def close():
root.destroy()
def show():
root.deiconify()
button.config(text = 'click to shutdown', command = close)
def hide():
root.withdraw()
time.sleep(10)
show()
button = Tkinter.Button(text = 'click for hide for 10 secs', command = hide)
button.pack()
root.mainloop()