0

こんにちは!

PySide を使用して Python GUI を開発しています。私が機能させようとしている機能の 1 つは、システムのユーザーからのログイン試行回数をカウントする機能です。これは、input() コマンドを使用する非 GUI アプリケーションでは非常に簡単ですが、self.lineEdit.returnPressed.connect() コマンドを理解するのに苦労しています。

以下に示すように、最大​​ 3 回のログイン試行を許可する While ステートメントがあります。ただし、キーボード入力を監視するために通常使用する方法を試してみると、次のようになります。

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

ただし、GUI で user_barcode を lineEdit に基づいているため、上記のアプローチは機能しません。input() を self.lineEditScanBarcode.text() に置き換えると、while ステートメントが自動的に 3 回繰り返され、lineEdit への入力は 1 つだけになります。すなわち。ユーザー名を入力して Enter キーを押すと、自動的に 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.")

ここで見逃している明らかなトリックはありますか?input() アクションのように動作するように、 returnPressed アクションを使用する方法があることを願っています。そうすれば、反復の開始時に returnPressed アクションを実行でき、スクリプトは、続行する前に lineEdit で Enter キーが押されるのを待ちます。

誰にもアイデアはありますか?

ありがとう!

4

1 に答える 1

2

(PySide スタイルの) GUI プログラミングの最も基本的な部分であるイベント ループが欠けています。

GUI はメイン イベント ループを実行します。ハンドラーを登録したイベントが見つかると、ハンドラーが呼び出されます。

ハンドラー関数はできるだけ早く返さなければなりません。ユーザー入力を待つことはできません。または、待機中は誰もイベントを処理していません。つまり、誰もあなたの次connectの を解雇することはありません。また、誰も画面を再描画したり、アプリが生きているかどうかをチェックする OS に応答したりしないことも意味します。

これは多くの場合、ロジックを「裏返し」にする必要があることを意味します。このようなもの:

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 アプリではあまり役に立ちません。他にもいろいろと怪しいものがあります。

しかし、これが基本的な考え方です。ユーザーが 4 回試行するのを待ってループしません。ユーザーの試行を登録し、関数へのすべての呼び出しで共有されるカウンターを保持します。

于 2013-09-25T01:56:19.553 に答える