Po prostu zaczynam w Qt i próbuję uzyskać uproszczony, działający przykład wzoru projektu kontrolera widoku.Qt Model/View/Controller Przykład
Do tej pory byłem w stanie używać sygnałów i gniazd do łączenia podstawowych widżetów, takich jak przyciski do QLabel
, i mieć widok zmodyfikowany po kliknięciu/zwolnieniu przycisku. Zobacz poniższy kod dla działającego przykładu tego (zaimplementowanego w klasie MainWindow
).
Próbuję zdefiniować klasę, w tym przypadku Game
, która będzie moim modelem. Chcę, aby Game
miał wszystkie dane i reguły biznesowe mojej całej aplikacji. Nie wymagam, aby Game
było czymś specyficznym dla Qt - bardzo dobrze mógłby być generyczny C++. Jednakże, w poniższym kodzie, ma on pewien specyficzny dla Qt kod do implementacji QTimer
, który jest przydatny do celów tego przykładu.
staram się osiągnąć dwie rzeczy w tym przykładzie:
- chcę mieć model, który jest w stanie wygenerować jakieś wydarzenie w sobie, jak zwiększający wartość zmiennej na upływ czasu, i ostatecznie zobaczymy, że ta zmiana w jakiś sposób odzwierciedliła się w widoku. Albo jeszcze lepiej,
timeout()
zQTimer
może być po prostu sygnałem, który jest podłączony do jakiegoś gniazda, który jest jakimś wydarzeniem, które ma miejsce w modelu. Używając kodu pokazanego poniżej, odbicie w widoku byłoby ustawieniemlabel_1
(część klasyMainWindow
) w celu wyświetlenia jednego z obrazów już zapisanych wimageOn
lubimageOff
(także należących do klasyMainWindow
). - Chcę, aby przycisk powiązany z
on_pushButton_clicked()
ion_pushButton_pressed()
był w stanie zmodyfikować niektóre wartości przechowywane w modelu. Następnie, zataczając pełne koło z punktem 1, aktualizację modelu należy odzwierciedlić w widoku.
Jeśli moja dotychczasowa terminologia jest niepoprawna lub niezgodna z terminologią Qt wzoru projektowego MVC, wybacz mi. Z zadowoleniem przyjmuję wszelkie wyjaśnienia w tej sprawie. Ponadto, jeśli podany przeze mnie przykładowy kod jest zbyt zawiły, aby zilustrować wzorzec projektowania MVC w Qt, jestem bardziej niż chętny do wyczyszczenia tablicy i rozpoczęcia z bardziej odpowiednim przykładem. Wszystko, co próbuję zrobić, to zacząć od Qt i MVC, ale w sposób, który zajmuje się bardziej złożonymi typami danych.
Próbuję opracować przykład, w którym mogę obsłużyć model i klasę, taką jak Game
, która jest potencjalnie złożona - nie jest to prosta lista QStringów lub coś, co może być bardziej proste. Przeglądając dokumentację związaną z MVC, natknąłem się na wiele przykładów, które wykorzystywały funkcję setModel()
do próbowania połączeń, które zasadniczo przedstawiam na liście 1 i 2. Problem polegał na tym, że nie mogłem zobaczyć sposobu użycia tego dokładnego podejścia z bardziej złożonym typem danych, takim jak Game
, który może być całym modelem danych dla kompletnej aplikacji (wiem, że Game
nie jest skomplikowany w tym przykładzie, ale może w końcu być). Potrzebuję czegoś, co jest skalowalne i rozszerzalne, coś, co zadziałałoby dla całej aplikacji. Jeśli te funkcje typu setModel()
nadają się do tego - co najprawdopodobniej mogłyby być, po prostu nie mogłem sam tego sobie wyobrazić - chciałbym wiedzieć, jak wdrożyć te w tym przykładzie dotyczące QLabel
i obrazów.
Kod:
gra.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();
}
Qt korzysta z podejścia model-widok, nie ma oddzielnego kontrolera. Czy próbujesz użyć rzeczy z widoku modelu Qt lub przetasować własne rzeczy MVC? Więc jakie jest prawdziwe pytanie? – hyde
Nie znam kosztów i korzyści związanych z modelem Qt w porównaniu z innymi rzeczami w grze MVC, ale nie widzę powodu, by pracować przeciwko ziarnu tylko ze względu na niego. Przypuszczam, że oznaczałoby to, że chcę używać rzeczy typu widoku modelu Qt.Nie próbuję zmusić kontrolera do miksu. Nie wiedziałem, że Qt nie wyróżniało natywnie kontrolerów. – nairware
Ogólny widok (z tego, co przeczytałem) jest taki, że widgety wygody są dobre dla małych rzeczy. Widok/standardowe modele są idealne, gdy potrzebujesz mieć jeden model danych i wiele widoków tych samych danych ... i wreszcie ... jeśli potrzebujesz dużych zbiorów danych, które reprezentują twoje własne struktury danych, niestandardowe modele są tam dla tego rodzaju wykonania. – jdi