一、简单介绍
今天记录一下在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层