我正在写一个基本的战争驾驶计划。我已经让它循环命令拉近附近的所有无线接入点。问题是我的停止按钮不起作用,我无法更新标签(我甚至不确定是否可以更新标签)。
import sys, os, subprocess, re
from Tkinter import *
missionGO = 0
count = 0
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.start = Button(frame, text="Start", fg="green",
command=self.startButtonClick)
self.start.grid(row=3)
self.stop = Button(frame, text="Stop", fg="red",
command=self.stopButtonClick)
self.stop.grid(row=3, column=1)
self.totalSSIDLabel = Label(frame, text="Current Access Points: ")
self.totalSSIDLabel.grid(row=0)
self.totalSSID = Label(frame, text=count)
self.totalSSID.grid(row=0, column=1)
def startButtonClick(self):
missionGO = 1
while (missionGO == 1):
wlan = getAccessPoints()
x = numberOfAccessPoints(wlan)
print x
return
def stopButtonClick(self):
missionGO = 0
return
def stop(event):
missionGO = 0
# Finds all wireless AP
def getAccessPoints():
X = subprocess.check_output("netsh wlan show network mode=Bssid",
shell=True)
return X
def numberOfAccessPoints(file):
count = 0
words = file.split()
for line in words:
if re.match('SSID', line):
count = count + 1
return count
#Main
root = Tk()
app = App(root)
root.mainloop()
答案 0 :(得分:4)
Tkinter是单线程的。这意味着当您处于while
内的startButtonClick
循环时,不会处理任何其他事件。在startButtonClick
功能完成
你需要记住你的程序已经在运行一个全局无限循环:事件循环。没有理由在其中加入另一个无限循环。当你想要一些东西永远运行时,诀窍是在事件循环上放一个迭代,然后当它运行时,它在事件循环上放置另一个迭代。
另一个关键是要确保循环的一次迭代很快 - 它需要在一秒钟之内(更像是100ms以下)或者UI会变得迟钝。
逻辑看起来像这样:
def startButtonClick(self):
self.missionGO = 1
self._do_one_iteration()
def _do_one_iteration(self):
if self.missionGO == 1:
wlan = getAccessPoints()
x = numberOfAccessPoints(wlan)
print x
# this adds another iteration to the event loop
self.after(10, self._do_one_iteration)
def stopButtonClick(self):
self.missionGO = 0
答案 1 :(得分:1)
我认为主线程挂在启动按钮单击的while循环中。由于它很忙,它甚至都不会注意到按下了停止按钮。
答案 2 :(得分:1)
我无法告诉你为什么你的停止按钮不起作用,但我想我已经了解了你的程序。我的建议是建立两个线程。 UI的第一个线程,第二个用于以给定间隔持续检查无线网络的线程(您当前的代码尽快检查 - 不好的做法,您应该在循环内暂停。
由于我没有在Tkinter处理过多线程,我只能为你提供入口点:
祝你好运!