首页 > 解决方案 > 使用 PyQt5 正确凭据后“重定向”用户

问题描述

我制作了一个 Django API,如果用户成功登录,它会返回。我使用该 API 结果在 PyQt 中登录用户。我的代码如下:

import json
import sys

import requests
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QLineEdit, QMessageBox, QLabel
from PyQt5.QtCore import pyqtSlot

from PyQtProject.request_login import querystring, headers


class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title = 'Login na aplicação'
        self.left = 600
        self.top = 400
        self.width = 380
        self.height = 200
        self.username = None
        self.password = None
        self.button = None

    def __call__(self, *args, **kwargs):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        # Create an username textbox
        self.username = QLineEdit(self)
        self.username.move(20, 20)
        self.username.resize(280, 40)
        self.username.setPlaceholderText('Usuário')

        # Create a password textbox
        self.password = QLineEdit(self)
        self.password.setEchoMode(QLineEdit.Password)
        self.password.move(20, 80)
        self.password.resize(280, 40)
        self.password.setPlaceholderText('Senha')

        # Create a button in the window
        self.button = QPushButton('Login', self)
        self.button.move(20, 140)

        # connect button to function on_click
        self.button.clicked.connect(self.on_click)
        self.show()

    @pyqtSlot()
    def on_click(self):
        username = self.username.text()
        password = self.password.text()

        querystring.update({'username': username, 'password': password})

        url = "http://localhost:8000/login_api/"

        response = requests.request("GET", url, headers=headers, params=querystring)

        result = json.loads(response.content)[0]['message']
        if result:
            pass
        else:
            QMessageBox.question(
                self, 'Erro', "Usuário não autenticado!", QMessageBox.Ok, QMessageBox.Ok
            )
            self.username.setText("")
            self.password.setText("")

    def upload_file_page(self):
        pass


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex()
    sys.exit(app.exec_())

我需要将用户“重定向”到 PyQt 中的上传文件“页面”。

我最初的想法是清除整个屏幕并用新的项目替换以前的项目。

我怎样才能做到这一点?

** “重定向”是指我想关闭前一个窗口并打开另一个窗口。

标签: pythondjangopyqt5

解决方案


在这种情况下,最好有一个类来处理类似于 Django 控制器的“页面”逻辑,以便让您的特定逻辑能够显示或隐藏页面。

另一方面,在您的情况下,请求是针对本地 url,但考虑到它也可以是远程 url,因此可能需要很长时间,因此它会阻塞 GUI,为避免这种情况,我已经实现了一个将居住的工作人员另一个线程避免冻结。

import sys
from functools import partial
import json

import requests

from PyQt5.QtWidgets import (
    QApplication,
    QLabel,
    QLineEdit,
    QMessageBox,
    QPushButton,
    QVBoxLayout,
    QWidget,
)
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, Qt, QThread, QTimer

from PyQtProject.request_login import querystring, headers


class LoginPage(QWidget):
    send_credentials = pyqtSignal(str, str)

    def __init__(self):
        super().__init__()
        self.title = "Login na aplicação"
        self.init_ui()

    def init_ui(self):

        self.setWindowTitle(self.title)

        # Create an username textbox
        self.username = QLineEdit(placeholderText="Usuário")
        self.password = QLineEdit(echoMode=QLineEdit.Password, placeholderText="Senha")
        self.button = QPushButton("Login")

        self.username.setFixedHeight(40)
        self.password.setFixedHeight(40)
        self.setFixedSize(380, 200)

        lay = QVBoxLayout(self)
        lay.addWidget(self.username)
        lay.addWidget(self.password)
        lay.addWidget(self.button, alignment=Qt.AlignLeft)

        # connect button to function on_click
        self.button.clicked.connect(self.on_click)

    @pyqtSlot()
    def on_click(self):
        username = self.username.text()
        password = self.password.text()

        self.send_credentials.emit(username, password)

    @pyqtSlot()
    def failed(self):
        QMessageBox.question(
            self, "Erro", "Usuário não autenticado!", QMessageBox.Ok, QMessageBox.Ok
        )
        self.username.clear()
        self.password.clear()


class UploadFilePage(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        lay = QVBoxLayout(self)
        lay.addWidget(QLabel("UploadFilePage"))


class RequestsWorker(QObject):
    logged = pyqtSignal(bool)

    @pyqtSlot(str, str)
    def login_request(self, username, password):
        querystring.update({"username": username, "password": password})
        url = "http://localhost:8000/login_api/"
        response = requests.request("GET", url, headers=headers, params=querystring)
        result = json.loads(response.content)[0]["message"]
        self.logged.emit(bool(result))


class Controller(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)

        thread = QThread(self)
        thread.start()

        self._requests_worker = RequestsWorker()
        self._requests_worker.logged.connect(self.onLogged)

        self._login_page = LoginPage()
        self._login_page.send_credentials.connect(self._requests_worker.login_request)
        self._login_page.show()

        self._upload_page = UploadFilePage()

    @pyqtSlot(bool)
    def onLogged(self, result):
        if result:
            self._login_page.close()
            self._upload_page.show()
        else:
            self._login_page.failed()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    controller = Controller()
    sys.exit(app.exec_())

推荐阅读