QT/C++ i trzy okna

0

Cześć to jest mój pierwszy post tutaj, ale forum jest mi znane i korzystam z wiedzy użytkowników. Nie zajmuję się pisaniem programów komercyjnie, robię to na własny użytek. Od jakiegoś czasu korzystam z dobrodziejstw jakie daje QT i powiem, że środowisko robi wrażenie. Do tej pory ograniczałem się do budowy programów jedno, góra dwu okienkowych i nie było problemów. Problem objawił się po pojawieniu się trzeciego okna. Nie jest on związany stricte z QT a wymianą danych w C++. Potrzebuję bardziej wskazania kierunku niż gotowego rozwiązania.

Mam trzy okna 1, 2, 3. Okno główne (1), w którym zaszyta jest procedura, która przetwarza dane w tablicy. Przetwarzanie trwa długo więc trzeba do niej czasem zaglądać co się dzieje. I teraz pytanie: Jak pozostałe okna (2,3) mogą odczytać dane z tej tablicy? Okna są osobnymi obiektami powołanymi w oknie 1 (klasa MainWindow). Okno 1 może dostać się do zmiennych z okien 2, 3, ale w drugą stronę jest już problem (przynajmniej ja mam problem). Być może trzeba inaczej podejść do budowy takiej aplikacji, ale nie mam na to pomysłu. Będę wdzięczny za wskazówki.

Pozdrawiam
Adam

3

Może zamiast wystawiać surowe dane z tablicy do czytania przez wszystkich, pójdź w stronę sygnałów i slotów.
Tak na szybko: niech okno 1 wystawi sygnał np. dataChanged() i zepnij to ze slotami z okien 2 i 3. W slotach już zrób sobie z tą informacją co chcesz.
Jeżeli używasz Qtowych modeli, to sygnał masz już załatwiony (QAbstractItemModel::dataChanged), wystarczy podpiąć sloty.

0

Ma to oczywiście sens, była to pierwsza moja myśl i to jest ostateczne koło ratunkowe, ale.... pomyślałem, że po co wypychać dane do innych obiektów skoro one ich nie potrzebują w danej chwili a proces w oknie 1 jest np. krytyczny i nie powinien robić rzeczy, które nie są potrzebne. Z drugiej strony trzeba utrzymywać kopie tablicy w jednym i drugim obiekcie. Może jest inne bardziej efektywne rozwiązanie.

0

Nikt Ci nie broni wysłać w tym sygnale już obrobionych danych w praktycznie dowolnej postaci. Zresztą zamiast dataChanged() może wysłać coś w stylu dataReady, z obsługi sygnału da się wyciągnąć przecież jego nadawcę. Jest to tyle problematyczne, że musisz wtedy pilnować jego czasu życia, ale skoro to i tak będzie parent to ma szanse się to udać. Co nie znaczy, że od strony architektury to dobre rozwiązanie.

0

Jest jeszcze opcja, że okno 2 lub 3 przesyła na slot okna 1 żądanie wysłania danych. Ustawia sobie flagę oczekiwania i jak okno 1 prześle dane na slot okna zgłaszającego potrzebę otrzymania danych to je prezentuje. I chyba tę metodę zastosuję. Wydaje się najbardziej optymalna. Jakby ktoś miał jeszcze inny pomysł to piszcie. Dzięki za uwagi.

0

Tak też można, pytanie czy te dane są aż tak ciężkie, że warto to już optymalizować.

0

miałem dla siebie zrobiony przykład jak przekazywać dane między oknami, jak go znajdę, to wrzucę jako przykład

0

tutaj jest mój przykład na wysyłanie tekstu między okienkami na przykładzie własnego slotu. Może coś z niego uda ci się zrozumieć

0

Ze slotami sobie radzę chodziło mi bardziej o to, czy nie ma innej metody, ale widzę, że tak będzie najprościej. Kod przeanalizuję, zawsze czegoś nowego można się dowiedzieć z przykładów.

0

Nie wiem czy dobrze rozumiem problem, ale nie podoba mi się rozwiązanie, które opisałeś. Okienka powinny odpowiadać za wyświetlanie danych i obsługę akcji użytkownika, a nie operacje na danych, w szczególności ciężkie.

Wobec tego, nie znając szczegółów proponowałbym taki podział:

  • osobna klasa do przechowywania danych i operacji na nich
  • może mieć worker QThread
  • może korzystać z QtConcurrent
  • może korzystać z QThreadPool
  • podział na model i widok
  • model posiada dane, operuje na nich
  • widok to obecne klasy okienkowe (albo ich część)

https://doc.qt.io/qt-5/model-view-programming.html

0

@kq:

osobna klasa do przechowywania danych i operacji na nich
może mieć worker QThread
może korzystać z QtConcurrent
może korzystać z QThreadPool

Może zrobiłbyś tutoriala do tych wyżej wymienionych klas ? Szukam czegoś lekkostrawnego (już znam odpowiedź)

@kq:

To spoko temat, ale na razie ciężko u mnie z czasem. Grudzień/styczeń może

wynajdź czas please :D

podział na model i widok
model posiada dane, operuje na nich
widok to obecne klasy okienkowe (albo ich część)

w model/widok już jest dużo jazdy. Jest to bardzo trudne i teraz pytanie jest takie, czego on używa do wyświetlania w widoku ?

Jeżeli używa:
QTableWidget Class - to widok sam dostosuje się do otrzymanych danych, zakładając, że przechowuje to w formie tabelarycznej np w macierzy

Jeżeli używa
QTableView Class - no i tutaj jest kilka kwestii co chce zrobić:

  1. Czy będzie chciał mieć edycję każdego z pól ? Jeżeli tak, to da się to zrobić ale jest to trochę trudne
  2. Będzie miał większą kontrolę nad przekazywanymi danymi - będzie mógł przekazać, to co chce, co więcej, będzie mógł nawet zablokować wybrane komórki które mają być poddane edycji
  3. Co jeśli będzie chciał dodawać i usuwać za pomocą zaznaczenia ? Da się to zrobić ale trzeba sporo poczytać dokumentacji

Temat model/widok przerobiłem ale nie do końca dokładnie, gdyby ktoś podzielił się wiedzą i kodem, to byłoby dobrze, bo od siebie też bym wrzucił kod (dużo kodu) na ten temat i moglibyśmy przedyskutować to wszystko aby lepiej zrozumieć temat, bo to fakt, jest bardzo trudne ale jak się to opanuje to bardzo fajnie robi się w tym tabele z danymi

1

@zkubinski: co do QThread, QThreadPool to nie potrzeba Ci tutoriala, tylko potrzeba zrozumieć co to są wątki, czym jest pula wątków. W sumie potem QtConcurrent stanie się oczywiste. Robiłeś kiedyś cokolwiek wielowątkowego?

2
zkubinski napisał(a):

Może zrobiłbyś tutoriala do tych wyżej wymienionych klas ? Szukam czegoś lekkostrawnego (już znam odpowiedź)

A może kq powinien napisać książkę?
Prościej by było jakbyś pokazał kod! Albo dał link do projektu na github/gitlab.

0

Taka mała uwaga... dane przetwarzane i przechowywane są w tablicy jednowymiarowej (int tablica[0xFFFF];) a nie w tabeli. Domyślam się, że pobieranie/zapisywanie danych do tabeli to wyższa szkoła jazdy. Też chętnie zapisze się na taki tutoriala.

0

tablicę jednowymiarową traktuj jak macierz 1x1 - spokojnie taką macierz załadujesz do widoku QTableWidget, musisz utworzyć z tej tablicy model, potem ten model ładujesz do widoku.

Tylko problem jest w tym, że nie mam na to na razie sensownego przykładu, bo wszystko mam zrobione na bazie danych ale pracuję nad takim przykładem, bo moja nauka model/widok jeszcze się nie zakończyła

0

Jak najbardziej możesz mieć jednowymiarowe dane (np. QListView z takich korzysta). Sama forma w jakiej trzymasz dane to tylko detal, który ta abstrakcja ukrywa.

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