2013-09-25 31 views
0

G'day!PySide信號/迭代循環槽

我正在使用PySide開發Python GUI。我試圖獲得功能的功能之一是能夠計算來自系統用戶的登錄嘗試次數。對於使用input()命令的非GUI應用程序來說,這非常簡單,但我在使用self.lineEdit.returnPressed.connect()命令時遇到了一些麻煩。

正如您在下面看到的,我有一條While語句允許最多3次登錄嘗試。但是,如果我嘗試和使用的方法,我通常使用監控鍵盤輸入,如:

n = 1 
while n < 4: 
    user_barcode = input() 
    if user_barcode == 'James': 
     print("Welcome James!") 
    else: 
     print("User not recognised, please try again.") 
     n = n + 1 

print("Sorry, you are not a recognised user of this system.") 
exit 

然而,現在我的立足關user_barcode一個lineEdit在GUI中,上述方法不工作。如果我用self.lineEditScanBarcode.text()替換input(),則while語句會自動迭代3次,只有1個輸入進入lineEdit。 IE瀏覽器。我輸入一個用戶名,點擊回車,它會自動迭代3次。在每次迭代開始之前,我如何「詢問」輸入lineEdit?

我猜我必須使用信號/插槽的意識形態,但我的理解是,我將不得不使用self.lineEditScanBarcode.returnPressed.connect()操作將lineEdit輸入引導到單獨的函數。我已經在下面瞭解了一下,但這是一個火車殘骸!

def Login(self): 
     global user_barcode 
     user_barcode = self.lineEditScanBarcode.text() 

     i = 1 
     while i < 4: 

      print(i) 

      self.lineEditScanBarcode.returnPressed.connect(LoginAttempt) 

      def LoginAttempt(self): 

       with open('Users.csv', 'rt') as f: 
        reader = csv.reader(f) 
        for row in reader: 
         for field in row: 
          if field == user_barcode: 
           global row_number 
           row_number = n 
           self.LoggedIn() 

       if user_barcode == 'Calibration': 
        self.lineEditScanBarcode.clear() 
        showCalibrationCertificate.show() 

       else: 
        if user_barcode not in open('Users.csv', 'r').read(): 
         print("Unauthorised access request.") 
         i = i + 1 
         self.lineEditScanBarcode.clear() 
         self.LCDLoginAttempt.display(i-1) 
      next 

     print("Sorry, you are not an authorised user of this system. Please contact the system administrator for further clarification, or if you feel this is an error.") 

是否有一些明顯的技巧我在這裏失蹤?我希望有一種方法可以使用returnPressed操作,這樣它就像input()操作一樣。這樣,我可以在迭代開始時執行returnPressed操作,並且腳本在繼續之前等待enterEdit上的Enter鍵被按下。

任何人有任何想法?

謝謝!

回答

2

您錯過了(PySide風格)GUI編程的最基本部分:事件循環。

GUI運行主事件循環。每當它發現你註冊一個處理程序的事件時,它就會調用你的處理程序。

您的處理函數必須儘快返回。它不能坐在等待用戶輸入,或者沒有人在等待時處理任何事件。這意味着沒有人會打開你的下一個connect,因爲沒有人會這樣做。這也意味着沒有人會重新繪製屏幕或響應操作系統檢查您的應用程序是否還活着或其他。

這通常意味着您需要將您的邏輯從裏面轉出。事情是這樣的:

def Login(self): 
    global user_barcode 
    self.login_attempts = 1 
    self.lineEditScanBarcode.returnPressed.connect(LoginAttempt) 

def LoginAttempt(self): 
    user_barcode = self.lineEditScanBarcode.text() 
    # all the stuff that validates the barcode 
    if valid: 
     self.LoggedIn() 
     return 
    print("Unauthorised access request.") 
    self.login_attempts += 1 
    self.lineEditScanBarcode.clear() 
    self.LCDLoginAttempt.display(self.login_attempts-1) 
    if self.login_attempts == 4: 
     print("Sorry, you are not an authorised user of this system. Please contact the system administrator for further clarification, or if you feel this is an error.") 
     # probably want to do something here... disconnect the signal? quit? 

當然是print聲明不太可能是在一個GUI應用程序非常有用的。而其他各種事情似乎是可疑的。

但這是基本的想法。你不會循環,等待用戶做四次嘗試;您註冊用戶嘗試,並保留一個計數器,該計數器在您的函數的所有調用中共享。

+0

我應該規定我對PySide和GUI非常新鮮。我已經閱讀了大量的文檔,但我還沒有掌握事件處理程序的想法。感謝您的詳細信息,這使得它更清晰了!我會繼續努力,看看我能想出什麼。謝謝! – jars121

+2

@ jars121:您第一次編寫基於事件循環的(或其他異步)程序時,無論是GUI還是網絡服務器,它都是一個很難逾越的概念障礙,並且通常教程對於幫助你克服它。希望現在你知道你在找什麼,你會很容易找出答案。一旦這個想法點擊你的頭,這並不難。 – abarnert

+0

感謝隊友,非常感謝! – jars121