python - 使用 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 中的上传文件“页面”。
我最初的想法是清除整个屏幕并用新的项目替换以前的项目。
我怎样才能做到这一点?
** “重定向”是指我想关闭前一个窗口并打开另一个窗口。
解决方案
在这种情况下,最好有一个类来处理类似于 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_())