Qt, dodawanie QML do Widget application

0

Ktokolwiek widział, ktokolwiek wie. Qt framework.
Od dwóch dni męczę się ze ścianą.

Mam Qt Widgets Application, w której moją główną klasą do wyświetlania obiektów, jest moja klasa dziedzicząca po QGraphicsView i zawierająca w sobie QGraphicsScene.
Ostatnio naszła mnie ochota na popróbowanie pisania sobie czegoś w QML ( do czego powinienem użyć Qt Quick Application).
Chciałbym dodać sobie na razie kilka elementów w ramach ćwiczeń do tej aplikacji, i dopiero następną zrobić sobie w Qt Quick Application. Postanowiłem spróbować zagłębić się trochę w temat i dowiedzieć, jak można dodawać elementy z QML do aplikacji z QGraphicsScene. No i tutaj zaczęły się schody.

Aplikacja którą mam, nie używa klasy QMainWindow ani QWindow, tylko QGraphicsView/QGraphicsScene- to jest już podstawowy mankament ( o tym później). W dokumentacji i na stackoverflow znalazłem kilka możliwych sposobów na dodanie obiektów QML do Widget Application, ale niektóre są już nieaktualne z racji nowej wersji Qt ( mowa o użyciu klasy QDeclarativeView).

Znalazłem jeden sposób który "działa", ale tylko połowicznie. Mianowicie, poprzez użycie klasy QQuickWidget...

 
    QQuickWidget *view =new QQuickWidget();
    view->resize(300,300);
    view->setResizeMode(QQuickWidget::SizeRootObjectToView );
    view->setSource(QUrl("qrc:/Button.qml"));//source qml, do sprawdzenia
    scene->addWidget(view);

Problem tutaj jest taki, że nie zachodzi automatyczne "update()" obiektu. Jeżeli jest to obiekt zawierający w sobie tylko jakieś statyczne elementy, to wystarczy to, ale do czegoś animowanego w sposób ciągły, musiałbym chyba dodać QTimer i odwołać się do slotu "update()" tego/tych widgetów ( update następuje po np. zminimalizowaniu okna). Nie zadowala mnie to do końca, ponieważ zobaczyłem, że jeżeli QQuickWidget zostanie dodany do okna QMainWindow albo QWindow, to jest animowany w sposób ciągły bez żadnych QTimerów ( i dlatego pytam tutaj, bo może ktoś wie jak wywołać to samo dla QGraphicsScene).

Drugim sposobem którym udało mi się coś osiągnąć, jest użycie klasy QQuickView i użycia createWindowContainer:

    QQuickView *view = new QQuickView();
    view->setSource(QUrl("qrc:/Button.qml"));
    QWidget *widget = QWidget::createWindowContainer(view,this->parentWidget()); // problemem może być ta linijka
    widget->setFixedSize(300,300);
    scene->addWidget(widget);
 

Problem tutaj polega, że mimo tego, że wyświetla mi się okienko okno/prostokąt w QGraphicsScene, to jest ono białe ( odnośnik do pliku jest dobry). Moje podejrzenia idą w stronę tej linijki:

 
QWidget *widget = QWidget::createWindowContainer(view,this->parentWidget());

Moja główna klasa dziedziczy po QGraphicsView i ma opcjonalnego rodzica ustawionego jako 0. Bez użycia "this->parentWidget()" dostaję ostrzeżenie: QGraphicsProxyWidget: cannot embed widget 0x6956190 which is not a toplevel widget, and is not a child of an embedded widget... tak więc muszę to dodać.

Trzecią, najnowszą możliwością jaka przyszła mi do głowy, jest dodanie w konstruktorze mojej klasy, klasy QMainWindow i ustawienie jej jako rodzica, oraz użycie show() dla rodzica (żeby wyświetlić inne elementy aplikacji-> bez tego, mam małe, białe okienko).
Później, mógłbym powtórzyć kod ze sposobu drugiego, ale zamiast:

scene->addWidget(...);
dodałbym
widget->show();
 

Tym sposobem, mam mój widget NA mojej scene ( nie wewnątrz niej). Aktualizuje się w czasie rzeczywistym oraz wyświetla wszystko, ale za to jest nad elementami które są już wewnątrz QGraphicsView ( zasłania je). Nie widziałem w QWidget żadnej metody do ustawiania onTop/Bottom, czy coś takiego, ale przyznam, że nie szukałem za bardzo.

Podsumowując:
1 sposób: wyświetla wewnątrz QGraphicsScene, ale nie odświeża- prawdopodobnie potrzebny QTimer i update().
2 sposób: wyświetla wewnątrz QGraphicsScene białe okienko, bez zawartości;
3 sposób: wyświetla nad QGraphicsScene, odświeża dynamicznie, blokuje możliwość kliknięcia na elementy które są pod nim.

Moje ogólne pytanie jest, po tym całym wywodzie i moim toku myślenia, czy może ktoś ma jeszcze jakiś inny, sprytny sposób, który pozwoli mi na osiągnięcie wyniku ze sposobu 1, + odświeżanie bez QTimera ( chciałbym nie używać QTimera, bo trochę tych elementów będzie).
Pozdro, i sorry za wywód, oraz jeśli pytam o jakąś głupotę, ale nie mam więcej pomysłów.

1

QQuickWidget to jest QWidget, czyli możesz go od razu wyświetlić, albo dodać do innego QWidget (np QMainWindow).
Wpychanie go do QGraphicsView to absurd, który da sporą karę do wydajności.

Coś mi się wydaje, że powinieneś się zainteresować QDeclarativeView.

"Głowna klasa dziedzicząca po QGraphicsView" to problem, to nie jest klasa przeznaczona do dziedziczenia (poza szczególnymi przypadkami).

0

Tak, wiem.
Tylko, że całą aplikację mam napisaną w oparciu o QGraphicsView, i nie bardzo mi się widzi przepisywanie wszystkiego:/.

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