Example Qt / View / Controller Model

I am just starting work in Qt and trying to get a simplified working example of a model for designing a model-view-controller.

Until now, I could use signals and slots to connect basic widgets, such as buttons, to QLabel , and change the view by pressing / releasing the button. See the code below for a working example of this (implemented in the MainWindow class).

I am trying to define a class, in this case Game , which will be my model. I want the Game have all the data and business rules for my entire application. I do not require Game be anything specific to Qt - it could very well be general C ++. However, in the code below, it has some Qt-specific code for implementing QTimer , which is useful for the purposes of this example.

I am trying to achieve two things in this example:

  • I want to have a model that can generate some kind of event within itself, for example, increase the value of a variable over time, and then ultimately see that the change is somehow reflected in the view. Or even better, timeout() QTimer may just be a signal that is connected to some slot, this slot is some kind of event that happens inside the model. Using the code below, the reflection in the view will be setting label_1 (part of the MainWindow class) to display one of the images already saved in imageOn or imageOff (also part of MainWindow ).
  • I want the button associated with the on_pushButton_clicked() and on_pushButton_pressed() slots to be able to change some value stored in the model. Then, starting a full circle with paragraph 1, let this update of the model be reflected in the view.

If my terminology is still incorrect or does not match the Qt terminology of the MVC design pattern, forgive me. I would like clarification on this. Also, if the sample code I provided is too confusing to illustrate the MVC design pattern in Qt, I'm more than ready to erase the slate and start with a more suitable example. All I'm trying to do is start with Qt and MVC, but with regard to more complex data types.

I am trying to develop an example in which I can handle a model and class such as Game , which is potentially complex, not a simple list of QStrings or something guaranteed to be more direct. When I looked at the Qt documentation related to MVC, I came across a lot of examples that used the setModel() function to try to establish the connections, which I mainly list in paragraphs 1 and 2 of the list. The problem was that I could not see a way to use this exact approach with a more complex data type such as Game , which could be the entire data model for the full application (I know that the Game in this example is not complicated, but it may be result). I need something scalable and extensible to work for the whole application. If these setModel() -type functions are suitable for this, which they most likely may be, I just could not figure it out on my own - I would like to know how to implement the ones in this example regarding QLabel and image .

the code:

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 

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

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

mainwindow.cpp

 #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)); } 

main.cpp

 #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(); } 
+8
model-view-controller qt signals-slots
source share
1 answer

The โ€œcontrollerโ€ in Qt can technically be represented by a separate subclass of QObject containing only slots. And you would connect this between your model and view.
But usually what I do (and see) is just to make your model business logic, and your view subclass contains methods for handling user interactions. The closest approach to the concept of the controller is when I have a QMainWindow (or dialog) class that represents the application, and it has a bunch of SLOTS on it. These slots are connected to the private signals of the user interface elements for their connection.

Example. In the main window there is a model, view and button. In init for the main window, I would set the model in the view and connect the โ€œclickedโ€ button to the slot in my refreshData() window. Then this slot will call the update method on the model, which will automatically propagate to the view. The main window thus acts as a controller.

What you would like to do is make some type of QAbstractItemModel or QStandardItemModel that represents your data and does what you want to update this data (such a timer as you suggested). Any view connected to the model will be able to see it because of the standard interface. You can also simply create a separate timer that puts data in an existing QStandardItemModel

Note on custom QAbstractItemModel classes

As @hyde pointed out, switching to a custom model can be a problem if you try to do this first before understanding the specific concrete classes of models well. Here's what I recommend doing:

  • Check out convenient widgets (QListWidget, QTableWidget, QTreeWidget).
  • Then try using QStandardItemModel with QListView / QTableView
  • Then we work with QTreeView
  • Finally, when you really need very individual modeling for existing data structures, you can work with the QAbstractItemModel subclass to use its own internal structure.
+7
source share

All Articles