2012-03-29 96 views
0

我正在寫一個基本的戰爭駕駛程序。我已經得到它來循環命令拉近所有無線接入點。問題是我的停止按鈕不起作用,我無法更新標籤(我甚至不確定是否可以更新標籤)。Python GUI按鈕不會執行

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

,請讓你的縮進直,因爲這是在Python至關重要。 – Constantinius 2012-03-29 09:45:04

+0

抱歉,當我將其複製到問題中時,它有所不同。 – iFetus 2012-03-29 09:46:54

回答

4

Tkinter是單線程的。這意味着,當您處於startButtonClick內部的while循環中時,不會處理其他事件。在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 
+0

我得到一個AttributeError:應用程序實例在'後'沒有屬性。任何想法是什麼? – iFetus 2012-03-30 00:59:47

+1

@iFetus:我應該說上面假設Tkinter.Tk中的「self」。在你的情況下,你需要使用'master.after'或'self.master.after'或其他。 ''之後'是所有小部件通用的Tkinter方法。 – 2012-03-30 01:14:35

+0

哦,我明白了!我得到了它的工作。謝謝你的幫助。 – iFetus 2012-03-30 01:33:47

1

我認爲主線程掛在啓動按鈕點擊的while循環中。由於它很忙,它甚至不會注意到已按下停止按鈕。

+0

這就是我的想法,但是在那附近呢? – iFetus 2012-03-29 10:17:02

+1

是的。你可以在不同的線程中處理UI事件(或者在不同的線程中進行工作)。您還可以檢查tkinter是否提供了「主循環」的替代方案,以便您可以編寫自己的主循環來處理UI事件和您在同一個線程中的工作。 – katzenversteher 2012-03-29 10:21:42

1

我不能確切地告訴你爲什麼你的停止按鈕不起作用,但我想我的想法是你的程序。我的建議是建立兩個線程。用戶界面的第一個線程,第二個用於不斷檢查無線網絡的給定時間間隔(您當前的代碼儘快檢查 - 不好的做法,您應該在循環內暫停)

由於我沒有在Tkinter中處理多線程,只能爲您提供切入點:

祝你好運!