Qt模型/视图/控制器示例

Qt模型/视图/控制器示例,qt,model-view-controller,signals-slots,Qt,Model View Controller,Signals Slots,我刚刚开始学习Qt,并试图获得一个简化的模型-视图-控制器设计模式的工作示例 到目前为止,我已经能够使用信号和插槽将按钮等基本小部件连接到QLabel,并在单击/释放按钮时修改视图。请参阅下面的代码,以获取该类的工作示例(在main窗口中实现) 我正在尝试定义一个类,在本例中是,Game,它将成为我的模型。我希望Game拥有整个应用程序的所有数据和业务规则。我不要求游戏>代码>是任何Qt特定的——它很好地可以是通用C++。但是,在下面的代码中,它确实有一些特定于Qt的代码来实现QTimer,这对

我刚刚开始学习Qt,并试图获得一个简化的模型-视图-控制器设计模式的工作示例

到目前为止,我已经能够使用信号和插槽将按钮等基本小部件连接到
QLabel
,并在单击/释放按钮时修改视图。请参阅下面的代码,以获取该类的工作示例(在
main窗口中实现)

我正在尝试定义一个类,在本例中是,
Game
,它将成为我的模型。我希望
Game
拥有整个应用程序的所有数据和业务规则。我不要求<代码>游戏>代码>是任何Qt特定的——它很好地可以是通用C++。但是,在下面的代码中,它确实有一些特定于Qt的代码来实现
QTimer
,这对于本例非常有用

在本例中,我试图实现两件事:

  • 我希望有一个模型,它能够在自身内部生成某种事件,比如随着时间的推移增加一个变量值,然后最终看到视图中以某种方式反映的变化。或者更好的是,
    QTimer
    timeout()。使用下面显示的代码,视图中的反射将是
    标签1
    (属于
    主窗口
    类)的设置,以显示已存储在
    图像ON
    图像OFF
    中的一个图像(也是
    主窗口
    类的一部分)
  • 我希望与按下按钮()上的
    关联的按钮和按下按钮()上的
    关联的按钮能够修改模型中存储的某些值。然后,以项目1为起点,将模型的更新反映在视图中
  • 如果到目前为止我的术语不正确或与MVC设计模式的Qt术语不一致,请原谅。我欢迎对此作出任何澄清。此外,如果我提供的示例代码过于复杂,无法在Qt中举例说明MVC设计模式,我非常愿意一笔勾销,从一个更合适的示例开始。我所要做的就是开始使用Qt和MVC,但要处理更复杂的数据类型

    我正在尝试开发一个示例,在这个示例中,我可以处理一个模型和类,比如
    Game
    ,它可能很复杂,而不是简单的qString列表或保证更直接的东西。当我浏览与MVC相关的Qt文档时,我遇到了许多使用
    setModel()
    函数尝试建立我在列表项1和2中概述的连接的示例。问题是,我看不到一种方法可以将这种精确的方法用于更复杂的数据类型,如
    Game
    ,它可能是完整应用程序的整个数据模型(我知道
    Game
    在本例中并不复杂,但最终可能是)。我需要一种可伸缩和可扩展的东西,一种适用于整个应用程序的东西。如果那些
    setModel()
    -类型的函数适合于此(它们很可能是这样的,我自己无法理解),我想知道如何实现本例中处理
    QLabel
    和图像的函数

    代码:

    game.h

    #ifndef GAME_H
    #define GAME_H
    
    #include <QtCore>
    
    class Game : public QObject {
    
        Q_OBJECT
    
    public:
        Game();
        void timed_job();
    
    private:
        QTimer *timer;
    };
    
    #endif // GAME_H
    
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
        class MainWindow;
    }
    
    class MainWindow : public QMainWindow {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();
        void on_pushButton_pressed();
    
    private:
        Ui::MainWindow *ui;
        QImage imageOn, imageOff;
    };
    
    #endif // MAINWINDOW_H
    
    \ifndef游戏
    #定义游戏
    #包括
    类游戏:公共QObject{
    Q_对象
    公众:
    游戏();
    void timed_job();
    私人:
    QTimer*定时器;
    };
    #endif//GAME_H
    
    game.cpp

    #include "game.h"
    #include <QtCore>
    
    Game::Game() {
    }
    
    void Game::timed_job() {
        timer = new QTimer(this);
        timer->start(1000);
        //connect(timer, SIGNAL(timeout()), this, SLOT(flip()));
    }
    
    #include <QImage>
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow) {
        imageOn.load(":/Files/On.jpg");
        imageOff.load(":/Files/Off.jpg");
    
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow() {
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked() {
        ui->label_1->setPixmap(QPixmap::fromImage(imageOff));
    }
    
    void MainWindow::on_pushButton_pressed() {
        ui->label_1->setPixmap(QPixmap::fromImage(imageOn));
    }
    
    #include <QtGui/QApplication>
    #include <QLabel>
    #include "mainwindow.h"
    #include "game.h"
    
    int main(int argc, char *argv[]) {
        QApplication a(argc, argv);
    
        MainWindow w;
    
        w.show();
    
        return a.exec();
    }
    
    #包括“game.h”
    #包括
    Game::Game(){
    }
    void Game::timed_job(){
    计时器=新的QTimer(此);
    定时器->启动(1000);
    //连接(计时器、信号(超时())、此、插槽(翻转());
    }
    
    main window.h

    #ifndef GAME_H
    #define GAME_H
    
    #include <QtCore>
    
    class Game : public QObject {
    
        Q_OBJECT
    
    public:
        Game();
        void timed_job();
    
    private:
        QTimer *timer;
    };
    
    #endif // GAME_H
    
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
        class MainWindow;
    }
    
    class MainWindow : public QMainWindow {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();
        void on_pushButton_pressed();
    
    private:
        Ui::MainWindow *ui;
        QImage imageOn, imageOff;
    };
    
    #endif // MAINWINDOW_H
    
    \ifndef主窗口
    #定义主窗口
    #包括
    名称空间用户界面{
    类主窗口;
    }
    类主窗口:公共QMainWindow{
    Q_对象
    公众:
    显式主窗口(QWidget*parent=0);
    ~main窗口();
    专用插槽:
    单击按钮时无效();
    按下按钮时无效();
    私人:
    Ui::MainWindow*Ui;
    QImage imageOn,imageOff;
    };
    #endif//main窗口
    
    main window.cpp

    #include "game.h"
    #include <QtCore>
    
    Game::Game() {
    }
    
    void Game::timed_job() {
        timer = new QTimer(this);
        timer->start(1000);
        //connect(timer, SIGNAL(timeout()), this, SLOT(flip()));
    }
    
    #include <QImage>
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow) {
        imageOn.load(":/Files/On.jpg");
        imageOff.load(":/Files/Off.jpg");
    
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow() {
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked() {
        ui->label_1->setPixmap(QPixmap::fromImage(imageOff));
    }
    
    void MainWindow::on_pushButton_pressed() {
        ui->label_1->setPixmap(QPixmap::fromImage(imageOn));
    }
    
    #include <QtGui/QApplication>
    #include <QLabel>
    #include "mainwindow.h"
    #include "game.h"
    
    int main(int argc, char *argv[]) {
        QApplication a(argc, argv);
    
        MainWindow w;
    
        w.show();
    
        return a.exec();
    }
    
    #包括
    #包括“mainwindow.h”
    #包括“ui_main window.h”
    主窗口::主窗口(QWidget*父窗口):
    QMainWindow(父级),
    用户界面(新用户界面::主窗口){
    imageOn.load(“:/Files/On.jpg”);
    imageOff.load(“:/Files/Off.jpg”);
    用户界面->设置用户界面(此);
    }
    MainWindow::~MainWindow(){
    删除用户界面;
    }
    void主窗口::在按钮上单击(){
    ui->label_1->setPixmap(QPixmap::fromImage(imageOff));
    }
    void main window::在按下按钮时(){
    ui->label_1->setPixmap(QPixmap::fromImage(imageOn));
    }
    
    main.cpp

    #include "game.h"
    #include <QtCore>
    
    Game::Game() {
    }
    
    void Game::timed_job() {
        timer = new QTimer(this);
        timer->start(1000);
        //connect(timer, SIGNAL(timeout()), this, SLOT(flip()));
    }
    
    #include <QImage>
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow) {
        imageOn.load(":/Files/On.jpg");
        imageOff.load(":/Files/Off.jpg");
    
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow() {
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked() {
        ui->label_1->setPixmap(QPixmap::fromImage(imageOff));
    }
    
    void MainWindow::on_pushButton_pressed() {
        ui->label_1->setPixmap(QPixmap::fromImage(imageOn));
    }
    
    #include <QtGui/QApplication>
    #include <QLabel>
    #include "mainwindow.h"
    #include "game.h"
    
    int main(int argc, char *argv[]) {
        QApplication a(argc, argv);
    
        MainWindow w;
    
        w.show();
    
        return a.exec();
    }
    
    #包括
    #包括
    #包括“mainwindow.h”
    #包括“game.h”
    int main(int argc,char*argv[]){
    质量保证申请a(argc、argv);
    主窗口w;
    w、 show();
    返回a.exec();
    }
    
    Qt中的“控制器”在技术上可以由一个单独的
    QObject
    子类表示,该子类只包含插槽。您可以将其连接到模型和视图之间。
    但通常我所做的(和看到的)只是使您的模型包含业务逻辑,而您的视图子类包含处理其用户交互的方法。我最接近控制器的概念是当我有代表应用程序的QMainWindow(或dialog)类时,它上面有一堆插槽。这些插槽连接到专用UI成员信号,以将它们连接在一起

    示例:主窗口有一个模型、一个视图和一个按钮。在主窗口的init中,我将在视图中设置模型,并将“单击”按钮连接到我的窗口
    refreshData()上的插槽