Qt Modèle/Vue/Contrôleur Exemple
Je suis juste de commencer dans Qt, et d'essayer de sortir d'une procédure simplifiée, exemple de travail de conception modèle-vue-contrôleur de motif de conception.
Jusqu'à présent, j'ai été en mesure d'utiliser les signaux et les slots pour connecter des widgets de base comme les boutons-poussoirs à un QLabel
, et d'avoir le point de vue être modifié tant que le bouton est cliqué ou libéré. Voir le code ci-dessous pour un exemple de cette mise en œuvre dans le MainWindow
classe).
Je suis en train de définir une classe, dans ce cas, Game
, qui va être mon modèle. Je veux Game
à avoir l'ensemble des données et des règles de gestion de l'ensemble de mon application. Je n'ai pas besoin que Game
être n'importe quoi spécifiques de Qt--il pourrait très bien être générique en C++. Cependant, dans le code ci-dessous, elle a quelques Qt-code spécifique pour mettre en œuvre un QTimer
qui est utile pour les fins de cet exemple.
Je suis en train de réaliser deux choses dans cet exemple:
- Je veux avoir un modèle qui est capable de générer une sorte d'événement à l'intérieur de lui-même, comme l'incrémentation de la valeur d'une variable au fil du temps, et puis finalement voir le changement en quelque sorte reflète dans la vue. Ou mieux encore, la
timeout()
de laQTimer
pourrait simplement être le signal est connecté à certains fente, la fente étant un événement qui a lieu à l'intérieur du modèle. En utilisant le code ci-dessous, le reflet dans le point de vue, le réglage delabel_1
(une partie de laMainWindow
classe) pour afficher l'une des images déjà enregistrées dansimageOn
ouimageOff
(également partie de laMainWindow
classe). - Je veux avoir le bouton-poussoir associé à la
on_pushButton_clicked()
eton_pushButton_pressed()
fentes être en mesure de modifier la valeur stockée dans le modèle. Ensuite, la boucle avec l'article 1, que la mise à jour du modèle de l'être reflété dans l'affichage.
Si ma terminologie ainsi, la mesure est incorrecte ou incompatible avec Qt terminologie du modèle de conception MVC, pardonnez-moi. Je souhaite recevoir des précisions sur ce point. Aussi, si l'exemple de code que j'ai fourni est trop alambiqué pour illustrer le modèle de conception MVC en Qt, je suis plus que prêt à passer l'éponge et de commencer avec un plus appropriée exemple. Tout ce que je suis en train de faire est de commencer avec Qt et MVC, mais d'une manière qui porte sur des types de données complexes.
Je suis en train de développer un exemple dans lequel je peux gérer un modèle de classe et comme Game
qui est potentiellement complexes, et non pas une simple liste de QStrings ou quelque chose de garanti pour être plus straight-forward. Lorsque j'ai parcouru la documentation de Qt liées à la MVC, j'ai rencontré beaucoup d'exemples qui ont utilisé l' setModel()
fonction de l'essayer et de faire le lien je suis essentiellement en décrivant les éléments de la liste 1 et 2. Le problème était que je ne pouvais pas voir un moyen de l'utilisation de cette approche exacte avec de plus en plus complexes de type de données, comme Game
qui pourrait être l'ensemble du modèle de données pour une application complète (je sais Game
n'est pas complexe dans cet exemple, mais il pourrait être éventuellement). J'ai besoin de quelque chose qui est évolutif et extensible, quelque chose qui pourrait fonctionner pour l'ensemble de l'application. Si ces setModel()
-type de fonctions sont adaptés pour ce qu'ils très probablement pu être, je ne pouvais pas le comprendre sur mon propre--je voudrais savoir comment mettre en œuvre ces dans cet exemple traiter avec QLabel
et des images.
Code:
jeu.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();
}
Je ne connais pas les coûts et les avantages de l'intervalle Qt modèle-vue stuff vs rouler ma propre MVC chose, mais je ne vois aucune raison de travailler à contre-sens juste pour le plaisir de le faire. Je suppose que cela signifierait que je veux utiliser Qt modèle-vue des choses. Je ne suis pas d'essayer de forcer le contrôleur dans le mélange. Je ne savais pas Qt n'a pas nativement distinctes contrôleurs.
De l'avis général (de ce que j'ai lu), c'est que la commodité des widgets sont bonnes pour les petites choses. Le point de vue standard, les modèles sont parfaits pour quand vous avez besoin d'avoir un modèle de données et de nombreuses vues de ces mêmes données...et enfin...si vous avez besoin de faire d'énormes ensembles de données qui représentent vos propres structures de données, les modèles personnalisés sont là pour ce genre de performance.
Une bonne lecture sur l'intervalle Qt modèle-vue de l'approche: qt-project.org/doc/qt-4.8/model-view-programming.html
OriginalL'auteur nairware | 2012-11-16
Vous devez vous connecter pour publier un commentaire.
Un "contrôleur" dans Qt pourrait techniquement être représenté par un autre
QObject
sous-classe, ne contenant que les machines à sous. Et vous fil entre votre modèle et la vue.Mais normalement ce que je fais (et de voir) est de simplement faire de votre modèle contient la logique métier, et votre point de vue sous-classe contient les méthodes pour le traitement c'est les interactions de l'utilisateur. Le plus proche que je reçois pour le concept de contrôleur, c'est quand j'ai mon QMainWindow (ou dialogue) de la classe qui représente l'application, et a un tas de machines à sous. Ces fentes obtenir câblé au privé de l'INTERFACE utilisateur des membres des signaux de connecter entre eux.
Exemple: Votre fenêtre principale dispose d'un modèle, d'une vue et d'un bouton-poussoir. Dans l'init de la fenêtre principale, je mettrais le modèle dans la vue, et de connecter le bouton-poussoir "cliqué" à une fente sur ma fenêtre
refreshData()
. Cette fente appelait alors la "mise à jour" de la méthode sur le modèle, ce qui permettra de propager automatiquement à l'affichage. La fenêtre principale agit donc comme un contrôleur.Ce que vous voulez faire est de faire un certain type de
QAbstractItemModel
ouQStandardItemModel
qui représente vos données et est-ce que vous voulez mettre à jour des données (un timer comme vous l'avez suggéré). Tout afficher connecté le modèle sera en mesure de le voir à cause de l'interface standard. Vous pouvez aussi simplement faire un autre timer qui place les données dans unQStandardItemModel
Une remarque sur la coutume QAbstractItemModel classes
Comme l'a souligné @hyde, sauter dans un modèle personnalisé peut être un défi si vous essayez de le faire en premier, avant d'obtenir une bonne compréhension de l'existant en béton classes de modèle. Voici ce que je recommande de faire:
C'est peut-être juste une expérience subjective. C'est seulement complexe si vous commencez immédiatement, sans une compréhension préalable de l'existant, des modèles concrets. Une fois que vous savez comment ces travaux, il est assez facile d'obtenir une simple lecture seule personnalisé modèle. Je vais mettre à jour avec quelques infos. Merci!
Merci pour la liste de choses à faire. Je vais commencer et revenir avec de meilleures bases.
comment est complexe pour un programmeur, c'est subjectif, mais je pense que l'on peut objectivement dire que c'est plus complexe que n'importe quoi d'autre offert par Qt, surtout si vous ne comptez pas les choses comme OpenGL, où la complexité provient de l'extérieur de l'intervalle Qt.
Je pense que d'entrer dans la peinture, ou QGraphics transformations peuvent être tout aussi difficile. Encore une fois, c'est subjectif. Faire une lecture personnalisée uniquement modèle ne nécessite 3-4 méthodes et il fonctionne.
OriginalL'auteur jdi