一个简单的基于Qt的MVC框架

发布于:2024-07-12 ⋅ 阅读:(149) ⋅ 点赞:(0)

如下是一个简单的基于Qt的MVC框架示例,其中模型(Model)中的操作会在子线程中处理。这个示例将包括一个基本的视图(View)、控制器(Controller)和模型(Model)。

1. 项目结构

项目结构如下:

MyMVCApp/
├── main.cpp
├── model.h
├── model.cpp
├── view.h
├── view.cpp
├── controller.h
├── controller.cpp
├── mainwindow.ui
├── mainwindow.h
├── mainwindow.cpp

2. main.cpp

#include <QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

3. view.h

视图部分主要负责显示数据和用户交互。我们将使用一个简单的QMainWindow作为视图,其中包含一个按钮和一个标签。

#ifndef VIEW_H
#define VIEW_H

#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>

class View : public QWidget
{
    Q_OBJECT

public:
    explicit View(QWidget *parent = nullptr);

    QPushButton *getButton() const;
    QLabel *getLabel() const;

private:
    QPushButton *button;
    QLabel *label;
    QVBoxLayout *layout;
};

#endif // VIEW_H

4. view.cpp

#include "view.h"

View::View(QWidget *parent) : QWidget(parent)
{
    button = new QPushButton("Click me", this);
    label = new QLabel("Initial text", this);
    layout = new QVBoxLayout(this);

    layout->addWidget(button);
    layout->addWidget(label);

    setLayout(layout);
}

QPushButton* View::getButton() const
{
    return button;
}

QLabel* View::getLabel() const
{
    return label;
}

5. mainwindow.h

mainwindow.h中,我们将包含view.h并将其作为主窗口的一部分。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "controller.h"
#include "view.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    Controller *controller;
    View *view;
};

#endif // MAINWINDOW_H

6. mainwindow.cpp

mainwindow.cpp中,我们将初始化视图并连接控制器和视图的信号和槽。

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    controller(new Controller(this)),
    view(new View(this))
{
    ui->setupUi(this);
    setCentralWidget(view);

    // Connect button click to controller slot
    connect(view->getButton(), &QPushButton::clicked, controller, &Controller::handleButtonClicked);
    
    // Connect controller signal to update label
    connect(controller, &Controller::updateLabel, view->getLabel(), &QLabel::setText);
}

MainWindow::~MainWindow()
{
    delete ui;
}

7. controller.h

#ifndef CONTROLLER_H
#define CONTROLLER_H

#include <QObject>
#include "model.h"

class Controller : public QObject
{
    Q_OBJECT

public:
    explicit Controller(QObject *parent = nullptr);

signals:
    void updateLabel(const QString &text);

public slots:
    void handleButtonClicked();

private:
    Model *model;
};

#endif // CONTROLLER_H

8. controller.cpp

#include "controller.h"

Controller::Controller(QObject *parent) : QObject(parent), model(new Model(this))
{
    // Connect model signal to controller signal
    connect(model, &Model::dataProcessed, this, &Controller::updateLabel);
}

void Controller::handleButtonClicked()
{
    model->processData();
}

9. model.h

#ifndef MODEL_H
#define MODEL_H

#include <QObject>
#include <QThread>

class Model : public QObject
{
    Q_OBJECT

public:
    explicit Model(QObject *parent = nullptr);
    ~Model();

    void processData();

signals:
    void dataProcessed(const QString &result);

private:
    QThread workerThread;
};

#endif // MODEL_H

10. model.cpp

#include "model.h"
#include <QTimer>

class Worker : public QObject
{
    Q_OBJECT

public slots:
    void doWork()
    {
        // Simulate long-running task
        QThread::sleep(2);
        emit resultReady("Data processed in background thread");
    }

signals:
    void resultReady(const QString &result);
};

Model::Model(QObject *parent) : QObject(parent)
{
    Worker *worker = new Worker;
    worker->moveToThread(&workerThread);

    connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
    connect(this, &Model::operate, worker, &Worker::doWork);
    connect(worker, &Worker::resultReady, this, &Model::dataProcessed);

    workerThread.start();
}

Model::~Model()
{
    workerThread.quit();
    workerThread.wait();
}

void Model::processData()
{
    emit operate();
}

11. Worker类

model.cpp中定义一个Worker类,用于在子线程中执行任务。

class Worker : public QObject
{
    Q_OBJECT

public slots:
    void doWork()
    {
        // Simulate long-running task
        QThread::sleep(2);
        emit resultReady("Data processed in background thread");
    }

signals:
    void resultReady(const QString &result);
};

总结

这个示例包括视图(View)、控制器(Controller)和模型(Model)。
视图负责显示数据和用户交互,控制器处理用户输入并更新视图,模型在子线程中处理数据并通知控制器更新视图。
你可以根据需要扩展这个框架,添加更多的功能和复杂性。
希望这个示例对你有帮助!


网站公告

今日签到

点亮在社区的每一天
去签到