QT MVC开发模式

882 阅读3分钟

一、简单介绍

今天记录一下在Qt中使用MVC模式进行开发的过程。MVC(Model-View-Controller)是一种常见的软件架构模式,用于将应用程序的逻辑和用户界面分离开来。在Qt中,使用MVC模式可以大大提高应用程序的可维护性和可扩展性。通过将应用程序的逻辑和用户界面分离开来,可以更轻松地进行修改和调试,并且可以轻松地添加新的功能和视图。那么,如何在Qt中实现MVC模式呢?下面让我们一步一步来做一个简单的示例。

二、案例

1.Model 层

Model层负责提供数据,并把数据封装成数据对象,这里我们用一个User类来代表用户信息。User类包含两个属性:用户名(username)和密码(password)

User.h

class User
{
public:
    void setUsername(const QString& username);
    QString getUsername() const;
​
    void setPassword(const QString& password);
    QString getPassword() const;
​
private:
    QString m_username;
    QString m_password;
};

User.cpp

class User
{
public:
    void setUsername(const QString& username);
    QString getUsername() const;
​
    void setPassword(const QString& password);
    QString getPassword() const;
​
private:
    QString m_username;
    QString m_password;
};
​
void User::setUsername(const QString& username)
{
    m_username = username;
}
​
QString User::getUsername() const
{
    return m_username;
}
​
void User::setPassword(const QString& password)
{
    m_password = password;
}
​
QString User::getPassword() const
{
    return m_password;
}

2.View 层

View层负责处理与用户的交互,接收用户输入、显示结果等。在这个登录案例中,我们需要设计一个LoginWidget来实现用户登录的视图。

LoginWidget.h

class LoginWidget : public QWidget
{
    Q_OBJECT
​
public:
    LoginWidget(QWidget* parent = nullptr);
​
signals:
    void signalLogin(const QString& username, const QString& password);
​
private slots:
    void slotLogin();
​
private:
    QLineEdit* m_usernameLineEdit;
    QLineEdit* m_passwordLineEdit;
};

LoginWidget.cpp

LoginWidget::LoginWidget(QWidget* parent)
    : QWidget(parent)
{
    m_usernameLineEdit = new QLineEdit;
    m_passwordLineEdit = new QLineEdit;
    m_passwordLineEdit->setEchoMode(QLineEdit::Password);
​
    m_loginButton = new QPushButton("Login");
    connect(m_loginButton, &QPushButton::clicked, this, &LoginWidget::slotLogin);
​
    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(m_usernameLineEdit);
    layout->addWidget(m_passwordLineEdit);
    layout->addWidget(m_loginButton);
​
    setLayout(layout);
}
​
void LoginWidget::slotLogin()
{
    QString username = m_usernameLineEdit->text();
    QString password = m_passwordLineEdit->text();
​
    emit signalLogin(username, password);
}

3.Controller

Controller层作为桥梁连接Model和View,处理用户请求并响应相应的操作。在这个登录案例中,我们需要一个LoginController类来处理用户的登录请求,验证用户名和密码是否正确,并将结果传回给View层。

Controller.h

class LoginController : public QObject
{
    Q_OBJECT
​
public:
    LoginController(QObject* parent = nullptr);
​
public slots:
    void slotLogin(const QString& username, const QString& password);
​
signals:
    void signalLoginResult(bool result);
​
private:
    bool checkUser(const QString& username, const QString& password); // 模拟验证用户信息是否正确的函数
};

Controller.cpp

LoginController::LoginController(QObject* parent)
    : QObject(parent)
{
}
​
void LoginController::slotLogin(const QString& username, const QString& password)
{
    bool result = checkUser(username, password);
    emit signalLoginResult(result);
}
​
bool LoginController::checkUser(const QString& username, const QString& password)
{
    User user;
    user.setUsername("admin");
    user.setPassword("123456");
​
    if (user.getUsername() == username && user.getPassword() == password) {
        return true;
    } else {
        return false;
    }
}

4.建立连接

在MVC架构中,View层和Controller层应该是解耦的,需要通过信号槽机制进行连接。我们在主函数中创建一个User实例和一个LoginController实例,并将它们连接起来,并将LoginWidget添加到QWidget控件中进行显示。具体代码如下:

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
​
    QWidget* widget = new QWidget;
    QVBoxLayout* layout = new QVBoxLayout;
​
    LoginWidget* loginWidget = new LoginWidget;
    layout->addWidget(loginWidget);
    widget->setLayout(layout);
​
    User user;
    LoginController controller;
    QObject::connect(loginWidget, &LoginWidget::signalLogin, &controller, &LoginController::slotLogin);
    QObject::connect(&controller, &LoginController::signalLoginResult, [widget](bool result) {
        if (result) {
            QMessageBox::information(widget, "Login Success", "Login success.");
        } else {
            QMessageBox::warning(widget, "Login Failed", "Username or password is wrong.");
        }
    });
    widget->show();
    return app.exec();
}

在上面的代码中,我们创建了一个QWidget控件,并设置一个QVBoxLayout布局管理器。然后创建了一个LoginWidget视图,并将其添加到QWidget控件中进行显示。接着创建了一个User实例和一个LoginController实例,并将LoginWidget的signalLogin信号连接到LoginController的slotLogin槽函数上,以处理用户登录请求。最后,将LoginController的signalLoginResult信号连接到一个lambda槽函数上,根据验证结果弹出对话框提示用户。

三、小结

总之,实现MVC架构需要将软件的视图、数据和控制分离开来,使得软件的代码更加清晰易懂、易于维护和扩展。在Qt中,我们可以使用QWidget、QLineEdit、QPushButton等组件来实现视图层,使用数据模型来实现Model层,使用QObject和信号槽机制来实现Controller层