我有Gui,它有单独的线程但是我需要其中一个线程在按下按钮时变为活动状态,我的问题是当我按下按钮时它会创建一个无限循环,不断生成新线程。
所以我需要检查线程.isAlive()
是否通过,如果没有启动线程:
if ThreadedTask.isAlive() == True:
pass
else:
self.queue = Queue.Queue()
ThreadedTask(self.queue).start()
但是当我这样做时,我收到以下错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1437, in __call__
return self.func(*args)
File "./2trans.py", line 539, in RecvBtn_Click
if ThreadedTask.isAlive() == True:
TypeError: unbound method isAlive() must be called with ThreadedTask instance as first argument (got nothing instead)
有人可以告知造成这种情况的原因吗?为了完成起见,我在下面添加了完整的类和按钮功能:
class ThreadedTask(Thread):
def __init__(self, queue):
Thread.__init__(self)
self.daemon = True
self.queue = queue
def run(self):
proc = Popen("receivetest -f=/dev/pcan33".split(), stdout = PIPE)
if terminated == 1:
proc.kill()
payload = iter(proc.stdout.readline, "")
for line in payload:
if line[0].isdigit():
splitline = line.split()
self.dictAdd(splitline)
def dictAdd(self, info):
global mydict
can_ID = info[4]
p = PCANmsg()
p.dlc = int(info[5])
p.CANtime = float(info[0])
p.hdata0 = info[6]
p.hdata1 = info[7]
p.hdata2 = info[8]
p.hdata3 = info[9]
p.hdata4 = info[10]
p.hdata5 = info[11]
p.hdata6 = info[12]
p.hdata7 = info[13]
p.timing = 1
if can_ID in mydict.keys():
q = mydict[can_ID]
p.COUNT = q.COUNT + 1
p.PCANperiod = p.CANtime - q.CANtime
else:
p.COUNT = 1
p.PCANperiod = 0.0
mydict[can_ID] = p
s = '%06X : %3d %02X %02X %02X %02X %02X %02X %02X %02X\t %8.2F %8d ' %\
(int(can_ID,16),
p.dlc,
int(p.hdata0, 16),
int(p.hdata1, 16),
int(p.hdata2, 16),
int(p.hdata3, 16),
int(p.hdata4, 16),
int(p.hdata5, 16),
int(p.hdata6, 16),
int(p.hdata7, 16),
p.PCANperiod,
p.COUNT)
self.queue.put(s)
按钮功能:
def RecvBtn_Click(self):
if ThreadedTask.isAlive() == True:
pass
else:
self.queue = Queue.Queue()
ThreadedTask(self.queue).start()
try:
info = self.queue.get(0)
info_split = info.split()
if self.RecvList.size() < len(mydict):
for _i in mydict.keys():
self.RecvList.insert("end",'%06X : %3d %02X %02X %02X %02X %02X %02X %02X %02X\t %8.2F %8d ' %\
(int(_i,16),
mydict[_i].dlc,
int(mydict[_i].hdata0, 16),
int(mydict[_i].hdata1, 16),
int(mydict[_i].hdata2, 16),
int(mydict[_i].hdata3, 16),
int(mydict[_i].hdata4, 16),
int(mydict[_i].hdata5, 16),
int(mydict[_i].hdata6, 16),
int(mydict[_i].hdata7, 16),
mydict[_i].PCANperiod,
mydict[_i].COUNT))
else:
for i, listbox_entry in enumerate(self.RecvList.get(0, "end")):
list_split = listbox_entry.split()
if list_split[0] == info_split[0]:
self.RecvList.delete(i)
self.RecvList.insert(i, info)
else:
continue
# self.RecvList.insert("end", info)
self.window.after(20, self.RecvBtn_Click)
except Queue.Empty:
self.window.after(100, self.RecvBtn_Click)
答案 0 :(得分:2)
你需要在特定的Thread对象上调用isAlive()...如果你还没有创建一个,那么就不能调用isAlive()。将Thread对象保存在一个初始化为None的变量中,而不是检查isAlive()检查此变量是否为None - 如果是,则为其分配一个新的ThreadedTask对象并启动它。当线程终止时,将此变量重新分配给无。