Technologieaustausch

Ein einfaches MVC-Framework basierend auf Qt

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Das Folgende ist ein einfaches Qt-basiertes MVC-Framework-Beispiel, in dem Operationen im Modell (Modell) in untergeordneten Threads verarbeitet werden. Dieses Beispiel umfasst eine grundlegende Ansicht, einen Controller und ein Modell.

1. Projektstruktur

Die Projektstruktur ist wie folgt:

MyMVCApp/
├── main.cpp
├── model.h
├── model.cpp
├── view.h
├── view.cpp
├── controller.h
├── controller.cpp
├── mainwindow.ui
├── mainwindow.h
├── mainwindow.cpp
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3. view.h

Der Ansichtsteil ist hauptsächlich für die Anzeige von Daten und die Benutzerinteraktion verantwortlich.Wir werden ein einfaches verwendenQMainWindowAls Ansicht enthält es eine Schaltfläche und eine Beschriftung.

#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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

4. Ansicht.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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

5. Hauptfenster.h

existierenmainwindow.h, wir werden einbeziehenview.hund machen Sie es zu einem Teil des Hauptfensters.

#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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

6. Hauptfenster.cpp

existierenmainwindow.cpp, initialisieren wir die Ansicht und verbinden die Signale und Steckplätze des Controllers und der Ansicht.

#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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

10. modell.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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

11. Arbeiterklasse

existierenmodel.cppDefinieren Sie eins inWorkerKlasse zum Ausführen von Aufgaben in untergeordneten Threads.

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);
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Zusammenfassen

Dieses Beispiel umfasst Ansicht, Controller und Modell.
Die Ansicht ist für die Anzeige von Daten und Benutzerinteraktionen verantwortlich, der Controller verarbeitet Benutzereingaben und aktualisiert die Ansicht, und das Modell verarbeitet Daten in einem untergeordneten Thread und benachrichtigt den Controller, die Ansicht zu aktualisieren.
Sie können dieses Framework nach Bedarf erweitern und so mehr Funktionalität und Komplexität hinzufügen.
Ich hoffe, dieses Beispiel hilft Ihnen!