在反复阅读各种教程和在线参考资料之后,终于让我的第一个线程脚本“有点”运行了有点“因为我在启动过程中仍然遇到一些奇怪的错误。在
我的课程目标
在这个用于调试的简化实现中,您将看到我似乎不必要地使用了spinbox控制变量。实际的(较长的程序)控制变量应用于触发用户输入到数字框的验证例程。实际上是控制变量在程序启动时给了我一些“奇怪的错误”
我的简化代码如下:
import tkinter as tk
import threading
import time
class controlPanel():
def __init__(self, master):
self.root = master
self.buildWidgets()
def buildWidgets(self):
self.labelVar = 0
self.ctrlVar = tk.StringVar()
self.ctrlVar.set(str(self.labelVar))
self.delay = 0.5
#+++++++++++++++++++++++++++++++++
self.labelName = tk.Label(self.root, text="Current Value: ", padx=3, pady=3)
self.labelName.grid(row=0, column=0)
self.labelValue = tk.Label(self.root, text=str(self.labelVar), padx=3, pady=3)
self.labelValue.grid(row=0, column=1)
#+++++++++++++++++++++++++++++++++
self.spinboxName = tk.Label(self.root, text="Target: ", padx=3, pady=3)
self.spinboxName.grid(row=1, column=0)
self.spinBoxA = tk.Spinbox(self.root, from_=0, to=1000,
textvariable=self.ctrlVar,
width=10, justify=tk.CENTER)
self.spinBoxA.grid(row=1, column=1)
#+++++++++++++++++++++++++++++++++
self.goButton = tk.Button(self.root, text="Go", width=12,
command=self.goButtonFunction,
padx=3, pady=3)
self.goButton.grid(row=2, column=1)
#+++++++++++++++++++++++++++++++++
self.stopButton = tk.Button(self.root, text="Stop", width=12,
command=self.stopButtonFunction,
padx=3, pady=3)
self.stopButton.grid(row=2, column=0)
#+++++++++++++++++++++++++++++++++
#self.labelValue.update()
#self.spinBoxA.update()
self.root.update()
def goButtonFunction(self):
print('GO button clicked')
self.flgRun = True
def stopButtonFunction(self):
print('STOP button clicked')
self.flgRun = False
class controlThread(controlPanel):
def __init__(self, master, name):
self.root = master
self.name = name
controlPanel.__init__(self, self.root)
self.flgRun = False
self.flgRunLock = threading.Lock()
self.pollPeriod = 100 # polling period, in ms
self.thread1 = threading.Thread(target = self.towardsTarget,
name=self.name)
self.thread1.daemon = False
self.thread1.start()
#time.sleep(5)
self.pollFlgRun()
#+++++++++++++++++++++++++++++++++
def pollFlgRun(self): # polls self.flgRun every self.pollPeriod
if self.flgRun:
print('<< Entering pollFlgRun >>')
time.sleep(0.01)
self.towardsTarget()
#self.flgRunLock.acquire() # lock thread to reset self.flgRun
self.flgRun = False # reset self.flgRun
#self.flgRunLock.release() # release thread
self.root.after(self.pollPeriod, self.pollFlgRun)
#+++++++++++++++++++++++++++++++++
def towardsTarget(self):
delay = 0.01 # delay in seconds
time.sleep(delay)
print('<< Entering towardsTarget >>')
#self.flgRunLock.acquire()
print('self.labelVar : ', str(self.labelVar))
# Problem 1: the following reference to self.ctrlVar gave error everytime the
# program starts. The error>> "RuntimeError: main thread is not in main loop"
# subsequent click on controlPanel.goButton will still give the program behavior
# specified above (i.e. no more error on subsequent clicks on the "Go" button)
#
# Problem 2: and when placed in a lock.acquire()/release() block, clicking the
# controlPanel.goButton will freeze up program
print('self.ctrlVar : ', self.ctrlVar.get())
#self.flgRunLock.release()
# test self.flgRun as well in case reset by controlPanel.stopButton
while( self.flgRun and str(self.labelVar) != self.ctrlVar.get() ):
print('WHILE loop')
if( self.labelVar < int(self.ctrlVar.get()) ):
self.labelVar +=1
print('self.labelVar before sleep> ', self.labelVar)
time.sleep(delay)
print('self.labelVar AFTER sleep> ', self.labelVar)
self.labelValue["text"] = str(self.labelVar)
self.labelValue.update()
else:
self.labelVar -=1
print('self.labelVar before sleep> ', self.labelVar)
time.sleep(delay)
print('self.labelVar AFTER sleep> ', self.labelVar)
self.labelValue["text"] = str(self.labelVar)
self.labelValue.update()
if __name__ == '__main__':
root = tk.Tk()
ctrl = controlThread(root, "X-thread")
问题1:
class controlThread.towardsTarget()
内,print
语句
每次程序运行时,引用self.ctrlVar
都会导致错误
开始。错误是“RuntimeError:main thread is not in main
循环”。在controlPanel.goButton
)仍将提供程序
上面指定的行为(即,在以后单击“Go”按钮时不再出错)问题2:
print
语句放在
lock.acquire()/lock.release()
块,单击“Go”按钮
(controlPanel.goButton
)将冻结程序我已经阅读了以下两页和相关的链接
但是上面两页提到的解决方案对我来说没有多大意义,因为如果完全删除引用print
的print
语句,则根本不会出现错误消息“RuntimeError:main thread is not in main loop”。在
我的问题是
lock.acquire()/lock.release()
块能够解决
但最终却冻结了程序。怎么可能
“print”语句引用可以避免此问题
self.ctrlVar
到位了吗?在
目前没有回答
相关问题 更多 >
编程相关推荐