首页 > 解决方案 > 使用pyqt5 mvc进行窗口切换

问题描述

程序从login窗口开始。如何main menu通过单击切换login button到窗口login window

主应用程序.py

import sys
from PyQt5 import QtWidgets
from model.login_model import LoginModel
from controllers.login_ctrl import LoginController
from views.login_view import LoginView


# Ana uygulama sınıfı
class App(QtWidgets.QApplication):
    def __init__(self, sys_argv):
        super(App, self).__init__(sys_argv)
        # Ana uygulama login ekranından başlıyor
        self.model = LoginModel()
        self.main_controller = LoginController(self.model)
        self.main_view = LoginView(self.model, self.main_controller)
        self.main_view.show()


if __name__ == "__main__":
    app = App(sys.argv)
    sys.exit(app.exec())

登录视图.py

from PyQt5 import QtCore, QtWidgets
from views.login_view_ui import Ui_MainWindow


class LoginView(QtWidgets.QMainWindow):
    def __init__(self, model, main_controller):
        super().__init__()

        self._model = model
        self._main_controller = main_controller
        self._ui = Ui_MainWindow()
        self._ui.setupUi(self)

        # connect login button to controller
        self._ui.loginButton.clicked.connect(
            lambda: 
            self._main_controller.check_credentials(self._ui.usernameLineEdit.text(), 
                self._ui.passwordLineEdit.text()))

login_ctrl.py

from PyQt5 import QtCore


class LoginController(QtCore.QObject):
    def __init__(self, model):
        super().__init__()
        self._model = model

    def check_credentials(self, username, password):
        self._model.set_username(username)
        self._model.get_credentials()

        if password == self._model.get_password():
            print("Login success!")
        else:
            print("Login failed!")

登录模型.py

from PyQt5 import QtCore


class LoginModel(QtCore.QObject):
    def __init__(self):
        super().__init__()
        self.__username = ""
        self.__password = ""

    def set_username(self, username):
        self.__username = username

    def get_username(self):
        return self.__username

    def set_password(self, password):
        self.__password = password

    def get_password(self):
        return self.__password

    def get_credentials(self):
        self.__password = "pswd"

main_menu_view_.py

from PyQt5 import QtCore, QtWidgets
from views.main_menu_ui import Ui_Form


class MainMenuView(QtWidgets.QMainWindow):
    def __init__(self, model, main_controller):
        super().__init__()

        self._model = model
        self._main_controller = main_controller
        self._ui = Ui_Form()
        self._ui.setupUi(self)

标签: pythonmodel-view-controllerpyqtpyqt5

解决方案


您必须通知更改,在这种情况下添加一个发送新视图名称的信号:

class LoginController(QtCore.QObject):
    finished = QtCore.pyqtSignal(str)

    def __init__(self, model):
        super().__init__()
        self._model = model

    def check_credentials(self, username, password):
        self._model.set_username(username)
        self._model.get_credentials()

        if password == self._model.get_password():
            print("Login success!")
            self.finished.emit("menu_view")
        else:
            print("Login failed!")

然后在应用程序中创建字典中的所有视图,并将控制器的完成信号连接到 change_view 方法,以便它根据传输的名称更改其视图:

class App(QtWidgets.QApplication):
    def __init__(self, sys_argv):
        super(App, self).__init__(sys_argv)
        self._views = {}
        self.model = LoginModel()

        self.main_controller = LoginController(self.model)
        self.main_controller.finished.connect(self.change_view)
        login_view = LoginView(self.model, self.main_controller)
        self._views["login_view"] = login_view
        menu_view = MainMenuView(your_model, your_controller)
        self._views["menu_view"] = menu_view

        self.change_view("login_view")

    @QtCore.pyqtSlot(str)
    def change_view(self, name_view):
        view = self._views.get(name_view)
        if view is not None:
            view.show()

然后,如果您想要关闭登录窗口,您必须将该信号连接到 hide 或 close 方法:

class LoginView(QtWidgets.QMainWindow):
    def __init__(self, model, main_controller):
        super().__init__()

        self._model = model
        self._main_controller = main_controller
        self._ui = Ui_MainWindow()
        self._ui.setupUi(self)

        # connect login button to controller
        self._ui.loginButton.clicked.connect(self.on_clicked)
        self._main_controller.finished.connect(self.hide)
        # or self._main_controller.finished.connect(self.close)

    @QtCore.pyqtSlot()
    def on_clicked(self):
        self._main_controller.check_credentials(
            self._ui.usernameLineEdit.text(), 
            self._ui.passwordLineEdit.text()
        )

推荐阅读