2013-09-25 30 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