我的工作代码如下。
我有一套用Python操作的机器。我在Tkinter中有一个gui,但很多时候这些机器在启动时自动启动python代码无法运行。
我非常喜欢使用root.after()来启动多个任务并让它们继续运行的设计模式。我的问题是,这来自Tkinter库,当无线运行时," root = Tk()"会抛出错误。
我有两个问题
OR
我确实尝试在Tkinter的底层代码中查看是否只有Tkinter包含的其他库,但我不具备解码该库中正在发生的事情的技能。
此代码适用于连接的显示器:(它打印hello 11次然后结束)
from Tkinter import *
# def __init__(self, screenName=None, baseName=None, className='Tk', useTk=1, sync=0, use=None):
root = Tk() # error is thrown here if starting this command in headless hardware setup
h = None
count = 0
c = None
def stop_saying_hello():
global count
global h
global c
if count > 10:
root.after_cancel(h)
print "counting cancelled"
else:
c = root.after(200, stop_saying_hello)
def hello():
global h
global count
print "hello " + str(count)
count += 1
h = root.after(1000, hello)
h = root.after(1000, hello) # time in ms, function
c = root.after(200, stop_saying_hello)
root.mainloop()
如果这是无头运行 - 在远程计算机的ssh会话中,则返回此错误消息
回溯(最近一次呼叫最后一次):文件" tkinter_headless.py",行 5,在 root = Tk()File" /usr/lib/python2.7/lib-tk/Tkinter.py" ;,第1813行, init self.tk = _tkinter.create(screenName,baseName,className,interactive,wantobjects,useTk,sync,use) _tkinter.TclError:没有显示名称,没有$ DISPLAY环境变量
答案 0 :(得分:0)
您可以使用
threading
和threating.timer() 或使用自己的after()
和mainloop()
简单示例
import time
class TaskManager():
def __init__(self):
self.tasks = dict()
self.index = 0
self.running = True
def after(self, delay, callback):
# calcuate time using delay
current_time = time.time()*1000
run_time = current_time + delay
# add to tasks
self.index += 1
self.tasks[self.index] = (run_time, callback)
# return index
return self.index
def after_cancel(self, index):
if index in self.tasks:
del self.tasks[index]
def mainloop(self):
self.running = True
while self.running:
current_time = time.time()*1000
# check all tasks
# Python 3 needs `list(self.tasks.keys())`
# because `del` changes `self.tasks.keys()`
for key in self.tasks.keys():
if key in self.tasks:
run_time, callback = self.tasks[key]
if current_time >= run_time:
# execute task
callback()
# remove from list
del self.tasks[key]
# to not use all CPU
time.sleep(0.1)
def quit(self):
self.running = False
def destroy(self):
self.running = False
# --- function ---
def stop_saying_hello():
global count
global h
global c
if count > 10:
root.after_cancel(h)
print "counting cancelled"
else:
c = root.after(200, stop_saying_hello)
def hello():
global count
global h
print "hello", count
count += 1
h = root.after(1000, hello)
# --- main ---
count = 0
h = None
c = None
root = TaskManager()
h = root.after(1000, hello) # time in ms, function
c = root.after(200, stop_saying_hello)
d = root.after(12000, root.destroy)
root.mainloop()