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

如下是一个简单的基于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)。
视图负责显示数据和用户交互,控制器处理用户输入并更新视图,模型在子线程中处理数据并通知控制器更新视图。
你可以根据需要扩展这个框架,添加更多的功能和复杂性。
希望这个示例对你有帮助!

相关推荐

  1. 一个简单基于QtMVC框架

    2024-07-12 18:46:05       22 阅读
  2. 一个基于MySQL数据库课程设计基本框架

    2024-07-12 18:46:05       29 阅读
  3. MVC框架和Spring MVC基本流程

    2024-07-12 18:46:05       54 阅读
  4. 用Python做一个简单后端框架

    2024-07-12 18:46:05       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 18:46:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 18:46:05       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 18:46:05       58 阅读
  4. Python语言-面向对象

    2024-07-12 18:46:05       69 阅读

热门阅读

  1. Android系统中LogMessage在那个so库中,需要引用?

    2024-07-12 18:46:05       19 阅读
  2. MySQL SQL100道基础练习题

    2024-07-12 18:46:05       18 阅读
  3. tomcat

    tomcat

    2024-07-12 18:46:05      25 阅读
  4. 倾斜摄影实景模型到底能不能用

    2024-07-12 18:46:05       22 阅读
  5. 力扣题解(等差数列划分)

    2024-07-12 18:46:05       22 阅读
  6. ES6 Module 的语法(十二)

    2024-07-12 18:46:05       18 阅读
  7. 王者荣耀爬虫程序

    2024-07-12 18:46:05       22 阅读
  8. yarn的安装与配置 (秒懂yarn用法)

    2024-07-12 18:46:05       20 阅读
  9. 错误集1

    2024-07-12 18:46:05       20 阅读
  10. ES6 async 函数详解 (十)

    2024-07-12 18:46:05       22 阅读