Organizacja klas w QT (Menadżer żużlowy).

0

Sprawa polega na tym, że załóżmy, że mam MainWindow gdzie powiedzmy sobie jest button StartMeczu. Teraz mam sobie klasy WidgetMecz, która rysuje okno dla meczu oraz Mecz, która zawiera dane Druzyny, Zawodnicy, Punktacja, Biegi itd. I teraz nie wiem jak sobie dobrze rozplanować projekt. Jeżeli mam ten button StartMeczu to gdzie definiować connect ? W klasie MainWindow tak? Gdzie definiować slot dla tego przycisku w klasie Mecz? Ona potem ma narysować WidgetMecz? Czy może także ma to wszystko być w MainWindow i rysowanie WidgetMecz także ?
Idźmy dalej na WidgetMecz mam przycisk Dalej, który powoduje symulację kolejnych biegów. Główna pętla przetwarzająca to powinna być w klasie Mecz. W takim razie jak klasa Mecz ma na WidgetMecz prezentować na bieżąco wyniki skoro WidgetMecz został narysowany przez MainWindow? Chodzi mi to o gdzie mają być utworzone instancje klas Mecz, WidgetMecz no i ten przycisk jak ma zostać zdefiniowany, gdzie connect, gdzie slot.

Bardzo proszę o pomoc, jakieś naprowadzenie na rozwiązanie bo już kilka dni nad tym rozmyślam i odchodzi mi powoli zapał na pisanie tego. Przeglądam różne tutoriale, ale jakoś nigdzie nie mogę znaleźć rozwiązania.

1

Polecam zajrzeć do przykładów w dokumentacji Qt jak oni to rozwiązują ale w skrócie - instancje wszystkich klas trzymasz w MainWindow ( głównej klasie aplikacji ), connect tam gdzie masz buttona czyli w Twoim przykładzie powiedzmy że w konstruktorze MainWindow no a slot w klasie z którą łączysz akcje np wciśnięcia przycisku.
Naprawdę polecam zajrzeć do przykładów aplikacji Qt wtedy wszystko powinno być już dla Ciebie jasne ;)
Pozdrawiam ;)

1

Zainteresuj sie MVC.

0

Właśnie jeśli chodzi o MVC, nie potrafię jakoś tego ogarnąć co by miało być w moim przypadku w modelu, kontrolerze i widoku.

0

Tak się zastanawiam czyli załóżmy że mam zrobione MainWindow, NowaGraWindow, NowaGraController.

W MainWindow jest przycisk Start.

  1. Instancja NowaGraController jest składnikiem MainWindow.
  2. Klasa NowaGraController zawiera slot dla przycisku Start.
  3. Connect w MainWindow jest zdefiniowany tak ze wywoluje slot na rzecz obiektu NowaGraController.
  4. Składnikiem klasy NowaGraController jest NowaGraWindow.
  5. Slot w NowaGraController powoduje rysowanie NowaGraWindow.
  6. Teraz jest przycisk Zatwierdź w NowaGraWindow.
  7. Składnikiem klasy NowaGraWindow jest GraController.
  8. Connect dla Zatwierdź jest tak zdefiniowany że powoduje wywolanie slotu w GraController.
  9. Składnikiem GraController jest GraWindow, które jest rysowane w slocie dla przycisku Zatwierdź
    .
    .
    .itd

Dobrze myślę?

1

Ad 4 Nie. Kontroler tylko pośredniczy w wymianie informacji miedzy użytkownikiem a modelem i aktualizuje widok.
Tutaj jest ładnie opisany MVC http://doc.qt.digia.com/qq/qq10-mvc.html

0

To powiedz mi jeżeli mam klase Mecz. I pętla leci po 15 biegach meczu żużlowego. Dane wszystkie wyniki musza byc trzymane na czas calego meczu tzn caly czas musi istnieć obiekt Mecz. Po każdym biegu wyniki są prezentowane na Widgecie. W takim razie gdzie ma powstać instacja Mecz ? W Controllerze ? Skoro w kontrolerze nie istnieje zaden widget to jak on ma go odświeżać?

1

W głównej klasie aplikacji tworzysz klasę kontrolera pod którą podpinasz elementy GUI, zasada jest prosta - użytkownik ma dostęp TYLKO do kontrolera. Ten modyfikuje model ( którego klasę też masz w głównym oknie ) w którym jest cała logika. Następnie łączysz za pomocą SIGNAL&SLOT model z widokiem tak żeby widok mógł się odrysować gdy dane w modelu zostały zmienione. Mam nadzieje że teraz jest to dla Ciebie jasne ;)

0
emacs napisał(a):

W głównej klasie aplikacji tworzysz klasę kontrolera pod którą podpinasz elementy GUI,

To jak w klasie kontrolera są elementy GUI tzn buttony itd ? :/ bo teraz mnie trochę zmyliłeś.

W MainWindow tworzę obiekt widoku i kontrolera ? To po co ten kontroler co w nim ma być? Teraz się pogubiłem.

Jak kontroler modyfikuje model skoro model ma byc stworzony w widoku?

Czyli sygnały tworzę w modelu a gniazda w widoku?

Widoków też trzeba tworzyć tyle ile trzeba a one maja byc tworzone w MainWindow.

1

Zobacz zaakceptowana odpowiedź tu http://stackoverflow.com/questions/13422909/qt-model-view-controller-example
Kontrolerem w Qt bardzo często jest po prostu główna klasa aplikacji która pośredniczy za pomocą sygnałów i slotów między modelem i widokiem.
Czyli np gdy użytkownik w GUI na widoku ( np QListView ) zaznacza jakiś element i naciska przycisk "delete" to łączysz sygnał clicked() tego buttona w głównej klasie ze swoim slotem w którym wywołujesz na modelu model.remove() a model aktualizuje sobie widok.

0

Napisz mi łopatologicznie:

  1. Gdzie ma być definiowany connect.
  2. Gdzie mają powstawać obiekty modelu i widoku.
  3. Mam rozumieć ze kontrolerem ma być MainWindow? To przecież ta klasa będzie zawierać od cholery i więcej kodu.
0

Jeśli przejrzałeś linki które podesłałem to tam to jest fajnie opisane ja najwidoczniej nie tłumacze najlepiej ;)
Tak na prawdę to wszystko zależy od aplikacji jak duża jest, jak wiele widoków ma mieć , jak wiele modeli itp.
Ad 2 tam gdzie są wykorzystywane - jeśli np w GUI masz jakiś widget np TabWidget to każda strona będąc osobnym widgetem może mieć w sobie swój model i widok a wtedy w MainWindow masz tylko cos takiego

class MainWindow
{
private:
   MyWidget tab1;
   MyWidget tab2;
   MyWidget tab3;
   // itd...

}

a każdy widget obsługuje swoje widoki i modele

class MyWidget : public QWidget
{
private:
   QListView listView;
   QStandartItemModel model;
   // itd...
}

Co do kontrolera to w bardzo wielu przykładach w Qt to właśnie MainWindow pełni tą funkcję ale to Ty musisz wiedzieć czy potrzebujesz do tego dodatkowej klasy aby na przykład zyskać na czytelności kodu czy nie. W każdym razie ten magiczny "kontroler" to tylko pośrednik między użytkownikiem a model ewentualnie widokiem.

0

O właśnie trzeba tych klas używać do modeli i widoku?
QListView listView;
QStandartItemModel model;

Nie mogę zrozumieć tego jak to działa? Kurcze niby w c++ czuję się dobrze ale tego GUI i MVC nie mogę ogarnąć... a tak mi zależy...

A te wyświetlanie widgetów wykonuje się w MainWindow? Model i widok tworzę w MainWindow a później przekazuję jako parametr model do widoku i widok do modelu?

1

Qt ma kilka klas dla standardowych widoków jak List, Tree czy Table i kilka klas dla modeli ale nie jestem w stanie Ci tego tutaj opisać. Qt ma naprawdę dobra dokumentacje i mnóstwo poradników w sieci. Zajrzyj w te 2 linki i przestudiuj to solidnie a wszystko będzie dla Ciebie jasne.
Proszę
http://qt-project.org/doc/qt-5/model-view-programming.html
http://qt-project.org/doc/qt-5/modelview.html

Pozdrawiam ;)

1

Nie, tych klas nie uzywasz jako modeli. Modele to raczej klasy definiowane przez uzytkownika (kontrolery tez). Natomiast widoki moga dziedziczyc po roznych kontrolkach. Czaj przyklad:

Klasa mainWindowController (pseudokod)

class MainWindowController 
{
   MainWindowView * mainWindowView;
   
   MainWindowView() {
        mainWindowView = new MainWindowView();

        connect(mainWindowView, SIGNAL(buttonPressed()), this, SLOT(buttonPressed());

        mainWindowView->show();
   }

   // sygnaly i sloty pochodzace z widoku np:
   void buttonPressed() {
       //tutaj odpalane sa np. modele obslugujace klikniecie
   }
}

Klasa widoku MainWindowView

class MainWindowView : public QWidget
{
 //dziedziczymy po QWidget, mamy dostep do jej nieprywatnych metod i pol, dowolnie ustawiamy wlasny widok
}

PS
Kazdy wiekszy element programu powinien miec cos na wzor wlasnego kontrolera i widoku. Swietnie sie to sprawdza dla programow okienkowych, nie wiem jak to sie sprawdza i czy w ogole w grach. Ale mysle ta filozofia nada sie u Ciebie ale musisz dobrze wszystko zaplanowac.

1

@MateuszS nie myl koledze.
Oczywiście że te klasy może użyć jako modele dla swoich widoków przecież po to one tam są. Wszystko w zależności od tego czego potrzebujesz.
Jeżeli potrzebujesz gdzieś w grze np listę graczy z ich avatarami spokojnie możesz użyć QListView jako widok i QStandardItemModel jako model dla tego widoku ewentualnie zawsze możesz dziedziczyć po tych wbudowanych modelach / widokach i rozszerzać je o swoje "dodatki".

0

Powiedźcie mi jeszcze coś takiego. Jak mam te MainWindow. Stworze se swoje widoku które dziedziczą po QWidget. To rysuje je w MainWindow? Czy robię show dla tego widoku. Bo jak zrobie show to bede miec dwa okna. A tak bym nie chciał. Wiem że jest coś takiego jak setCentreWidget bodajże. Mogę jako argument dla tej funkcji podać ten WidokWidget ?? Jeśli tak to to setCentreWidget musi być wykonane w MainWindow tak? Mateusz twój kod jest dla mnie zrozumiały. Ale tak w MainWindow też muszę utworzyć obiekt tego dodatkowego kontrolera i widoku ? Czy jak? Jeżeli załóżmy będę mieć ten przycisk w MainWindow i ma on spowodować namalowanie tego nowego Widoku. To jak mają wygladać definicje tych obiektów w MainWindow? Gdzie te przyciski i jak połączyć pomiędzy tymi dwoma widokami ?

Kurde tak chciałbym ten temat ogarnąć. Nie myślałem że będzie tak opornie. Czyli generalnie dla nowej rzeczy typu Trening, Transfery, Stadion tworze po dwie klasy Model i Widok? Tylko chodzi mi o to jak to połączyć te wywołania z MainWindow? Jak tworzyć te obiekty w MainWindow i definiować połączenia przycisków dla tej relacji.

Mam sobie klasy MainWindow gdzie jest przycisk który ma mi narysować załozmy MeczWidget i mamy tez klase MeczController. Jak dla tego zdefiniować te połączenie i który obiekt w której klasie ma być zdefiniowany?

1

Kod ktory podalem uzywasz zamiast MainWindow. Jesli chcesz zeby QWidget nie byl w osobnym oknie musisz mu przekazac przez konstruktor wskaznik na widok nadrzedny:

mainWindowView = new MainWindowView();
trainingView = new TrainingView(mainWindowView); 

Jest taka zasada ze jezeli chcesz aby jakas kontrolka w Qt byla w jakims oknie albo okno w oknie to przekazujemy mu (najlepiej w konstruktorze) wskaznik do tego okienka, na ktorym wyswietlana jest kontrolka

0

No ok rozumiem. Ale dalej nie mam odpowiedzi na najbardziej nurtujące mnie pytanie. Gdzie definiować te następne Controllery i Widoki? Jak łączyć przycisk będący na jednym widoku aby spowodował narysowanie innego. Załóżmy że mam MainWindow, ZawodnicyWindow i ZawodnikInfoWindow. I pierwszy rysuje drugi a drugi trzeci. No i dla kazdego kontroller. I gdzie i jak to teraz definiować instancje tych klas ??

1

Nie czytasz tego co Ci podsyłam a to grzech ciężki.
Modele, widoki i kontrolery definiujesz tam gdzie ich używasz jeśli masz tylko jedno okno główne to definiujesz te klasy w MainWindow, jeśli masz wiele widgetów to odpowiednie klasy modeli, widoku i kontrolera definiujesz w klasie tego widgetu nawet napisałem ci kawałek takiego kodu wcześniej...
To nie jest wcale tak skomplikowana sprawa jak Ci się wydaje. Masz jakieś okno które ma coś przedstawiać np okno "transfery" to definiujesz sobie widget "transfery" i w nim definiujesz klasy modelu, widoku i jeśli potrzebujesz to kontrolera a w głównej klasie umieszczasz instancje klasy widgetu "transfery". Nie potrafię jaśniej. Jeśli jeszcze tego nie rozumiesz to musisz poświęcić trochę czasu i poszukać informacji w internecie jest tego mnóstwo uwierz mi. A w przykładach Qt masz to nawet zakodowane... wystarczy zerknąć.

0

No dobra, ale mam sobie teraz ten Widget. I w MainWindow mam se zadeklarowany. Super. Teraz mam w MainWindow przycisk który ma rysować widget i ma sie wyswietlic teraz widget ze swoimi przyciskami. To połączenie tego przycisku (connect) definiuje w MainWindow? Slot jest w Widgecie?

Jeżeli slot będzie w Widgecie to wtedy zostanie wywołana ta funkcja z Widgetu. I w niej robie sobie rysowanie typu newWidget(MainWindow) w sensie takim, że ma mi narysować ten nowy widok w tym samym oknie. Dobrze rozumuję?

Taki przykład (nawet nie pseudokod)

MainWindow

Button * przycisk;
przycisk = new Button();
MeczWidget * mecz;
mecz = new MeczWidget();

connect (przycisk,SIGNAL(clicked),mecz,SLOT(mecz->gniazdo()));

MeczWidget

MeczModel * model;

void gniazdo(){
model = new MeczModel();
// i teraz jak tu użyć tego ?? MeczWidget = new MeczWidget(mainWindow); 
}

czy może w MainWindow musi być MeczKontroller i w nim slot?? To w takim razie skąd wziaść poźniej w kontrolerze te mainWindow dla wykonania tego MeczWidget = new MeczWidget(mainWindow);

0

Hmm nie wiem czy to sie sprawdzi w praktyce ale zalozmy ze masz kontroler glowny KG. W tym kontrolerze definiujesz widok glowny (glowne okienko) i subkontrolery odpowiedzialne za np opcje, rozgrywke single/multi, jakies inne. W subkontrolerze odpowoedzialnym za rozgrywke tworzysz tez pewnie jakis ogolny widok okna rozgrywki. Ten subkontroler tez ma swoje subkontrolery odpowiedzialne za np rozegranie wyscigu, transfery itd. Takie drzewko robisz. Poza tym tak jak napisal @emacs. Proboj, napisz troche kodu, chocby glowny kontroler i jak bedziesz mial pytania to wklej kod i zapytaj konkretnie

0

Dobra po świętach spróbuję coś ruszyć jak będę mieć problemy to będę tu pisać. Będę wdzięczny za każdą pomoc.

A tak jeszcze z innej beczki chciałbym zapytać bo z tym Qt jakby mi się kiedyś udało to napisać to będzie problem żeby zarabiać na projekcie. Nie lepiej by to było zrobić w czymś innym SFML czy SDK ??

1 użytkowników online, w tym zalogowanych: 0, gości: 1