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

时间:2012-11-16 19:13:26

标签: qt model-view-controller signals-slots

我刚刚开始使用Qt,并尝试获得模型 - 视图 - 控制器设计模式的简化工作示例。

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

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

我试图在这个例子中实现两件事:

  1. 我希望有一个能够在其自身内部生成某种事件的模型,比如在一段时间内递增变量值,然后最终看到该变化以某种方式反映在视图中。或者更好的是,timeout()的{​​{1}}可能只是连接到某个插槽的信号,该插槽是在模型中发生的某个事件。使用下面显示的代码,视图中的反射将是QTimerlabel_1类的一部分)的设置,以显示已存储在MainWindow或{{1}中的一个图像(也是imageOn类的一部分)。
  2. 我希望与imageOffMainWindow广告位相关联的按钮能够修改模型中存储的某些值。然后,使用第1项完整循环,将模型的更新反映在视图中。
  3. 如果到目前为止我的术语不正确或与MVC设计模式的Qt术语不一致,请原谅我。我欢迎任何澄清。另外,如果我提供的示例代码对于在Qt中举例说明MVC设计模式而言过于复杂,我非常愿意擦除平板并开始使用更合适的示例。我所要做的就是开始使用Qt和MVC,但是处理更复杂的数据类型。

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

    代码:

    game.h

    Game

    game.cpp

    setModel()

    mainwindow.h

    QLabel

    mainwindow.cpp

    #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
    

    的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()));
    }
    

1 个答案:

答案 0 :(得分:8)

Qt中的“控制器”在技术上可以由单独的QObject子类表示,只包含插槽。你可以在模型和视图之间进行连线 但通常我所做的(和看到的)只是让你的模型包含业务逻辑,你的视图子类包含处理它的用户交互的方法。我最接近控制器概念的是当我有代表应用程序的QMainWindow(或对话框)类时,它上面有一堆SLOTS。这些插槽连接到私有UI成员信号以将它们连接在一起。

示例:您的主窗口有一个模型,一个视图和一个按钮。在主窗口的init中,我将在视图中设置模型,并将“clicked”按钮连接到窗口refreshData()上的插槽。然后,此插槽将调用模型上的“更新”方法,该方法将自动传播到视图。因此,主窗口就像一个控制器。

您想要做的是制作代表您的数据的某种类型的QAbstractItemModelQStandardItemModel,并执行您想要更新该数据的内容(您建议的计时器)。由于标准接口,连接到模型的任何视图都能够看到它。您还可以创建一个单独的计时器,将数据放入现有的QStandardItemModel

关于自定义QAbstractItemModel类的说明

正如@hyde所指出的那样,如果您在充分了解现有的具体模型类之前尝试先执行此操作,那么跳转到自定义模型可能是一个挑战。我建议这样做:

  1. 熟悉便利小部件(QListWidget,QTableWidget,QTreeWidget)
  2. 然后尝试使用QStandardItemModel和QListView / QTableView
  3. 然后使用QTreeView
  4. 最后,当您真正需要为现有数据结构进行非常自定义的建模时,您可以继续使用QAbstractItemModel来使其使用您自己的内部结构。