Teknologian jakaminen

Yksinkertainen MVC-kehys, joka perustuu Qt:hen

2024-07-12

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

Seuraavassa on yksinkertainen Qt-pohjainen MVC-kehysesimerkki, jossa mallin (Model) toiminnot käsitellään lapsisäikeissä. Tämä esimerkki sisältää perusnäkymän, ohjaimen ja mallin.

1. Hankkeen rakenne

Hankkeen rakenne on seuraava:

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. näkymä.h

Näkymä-osio vastaa pääasiassa tietojen näyttämisestä ja käyttäjän vuorovaikutuksesta.Käytämme yksinkertaistaQMainWindowNäkymänä se sisältää painikkeen ja etiketin.

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

5. pääikkuna.h

olla olemassamainwindow.h, otamme mukaanview.hja tee siitä osa pääikkunaa.

#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. mainwindow.cpp

olla olemassamainwindow.cpp, alustamme näkymän ja yhdistämme ohjaimen ja näkymän signaalit ja paikat.

#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. ohjain.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. malli.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. malli.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. Työväenluokka

olla olemassamodel.cppMäärittele yksiWorkerLuokka tehtävien suorittamiseen lapsisäikeissä.

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

Tee yhteenveto

Tämä esimerkki sisältää näkymän, ohjaimen ja mallin.
Näkymä vastaa tietojen näyttämisestä ja käyttäjän vuorovaikutuksesta, ohjain käsittelee käyttäjän syötteitä ja päivittää näkymän, ja malli käsittelee tietoja lapsisäikeessä ja kehottaa ohjainta päivittämään näkymän.
Voit laajentaa tätä kehystä tarpeen mukaan, mikä lisää toimintoja ja monimutkaisuutta.
Toivottavasti tämä esimerkki auttaa sinua!