0

天!

我正在使用 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 基于 GUI 中的 lineEdit,上述方法不起作用。如果我用 self.lineEditScanBarcode.text() 替换 input(),while 语句会自动迭代 3 次,只有 1 个输入到 lineEdit。IE。我输入一个用户名,按回车,它会自动迭代 3 次。如何在 lineEdit 开始每次迭代之前“要求”输入到 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 操作,并且脚本在继续之前等待在 lineEdit 上按下 enter 键。

有人有想法么?

谢谢!

4

1 回答 1

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 应用程序中不太可能非常有用。其他各种事情似乎都很可疑。

但这是基本思想。你不循环,等待用户进行四次尝试;您注册用户尝试,并保留一个在对您的函数的所有调用中共享的计数器。

于 2013-09-25T01:56:19.553 回答