Aktualizowanie wyswietlanego obrazka
-
Witam wszystkich!
Jestem licealistą samoukiem, uczę się QT od niedawna ale od 5 dni szukam po internecie i nie potrafie rozwiązać problemu.
Tworzę prosty automat komórkowy (gra w życie), gdzie w każdej iteracji będzie zmieniać się mapa złożona z pixeli. Mój kod w skrócie:
QImage MainWindow::simulationCreate(QGraphicsScene *graphic,int sizeX, int sizeY, int nucleons, int ** tableResults, int ** tableTemporary){ //->zmienne lokalne, tworzenie dynamiczne tablic, wybieranie miejsc dla "zarodków" itp //W poniższy sposób tworze i wyświetlam początkową mapę złożoną z pixeli QImage symulacja = QImage(sizeX,sizeY,QImage::Format_RGB32); graphic = new QGraphicsScene(this); graphic ->addPixmap(QPixmap::fromImage(symulacja)); ui->graphicsView->setScene(graphic); //->tutaj następują kolejne pokolenia, gdzie wartość poszczególnych pixeli zmieniam jak poniżej symulacja.setPixel(m,o,qRgb(0,0,0)); // , dzieje się to w pętli, setki, a nawet tysiące razy, i co jakiś cykl, chciałbym "odświeżać" pixmapę. Próbowałem np tak: graphic ->addPixmap(QPixmap::fromImage(symulacja)); ui->graphicsView->setScene(graphic); //ale to doprowadza do oczywistego wycieku pamięci i crashu programu. }
Proszę o pomoc, jak mogę aktualizować tą swoją pixmapę.
Z góry dziękuję -
Cześć,
Problem polega na tym, że ignorujesz wartość zwracaną z
addPixmap()
. Ta funkcja zwraca pointer do nowo utworzonego obiektu graficznego, który wyświetla pixmapę. Zapamiętaj go sobie w zmiennej i kiedy chcesz podmienić obrazek zawołaj na tej zmiennejsetPixmap()
z nowym obrazkiem.Nie ma potrzeby ponownie ustawiać sceny na widoku. Raz wystarczy.
-
Zmieniłem na taki układ:
QImage symulacja = QImage(sizeX,sizeY,QImage::Format_RGB32); QGraphicsPixmapItem * ptrToImage; graphic = new QGraphicsScene(this); ptrToImage = graphic->addPixmap(QPixmap::fromImage(symulacja)); ui->graphic->setScene(graphic); ptrToImage->setPixmap(QPixmap::fromImage(symulacja));
Dziękuję bardzo za odpowiedź, próbówałem chyba w ten sposób i właśnie mam problem z tą ostatnią linijką. Wywołane w ten sposób, mam use of incomplete type class QGraphicPixmapItem. Nie do końca wiem jak powieniem to tutaj ugryźć.
-
use of incomplete type class
oznacza, że używasz typu, który został zadeklarowany, ale nie zdefiniowany (tzw. forward declaration). W miejscu gdzie go używasz musi być widoczna pełna definicja.W skrócie: dodaj
#include <QGraphicsPixmapItem>
w pliku, gdzie używasz tej zmiennej. -
-
@Dawid said in Aktualizowanie wyswietlanego obrazka:
Zrobiłem własną funkcję opóźniającą i wszystko gra.
Brzmi jak zły pomysł. Zajmujesz całą moc procesora żeby symulował, że nic nie robi. Szkoda prądu (baterii w przypadku urządzeń mobilnych).
Jeśli chcesz symulować wolniej to wystartuj QTimer z częstotliwością jaką potrzebujesz i wykonuj krok symulacji na jego tyknięciu (sygnał timeout()). To również zapewni, że symulacja będzie chodziła z taką samą prędkością na różnych komputerach. Wszelkie opóźniacze to technologia z gatunku "u mnie działa" ;) -
tak wyglądał mój opóźniacz, ale zmienię go zgodnie z Twoją radą, to wrzucę niżej/zedytuje post.
void MainWindow::delay( int millisecondsToWait ){ QTime dieTime = QTime::currentTime().addMSecs( millisecondsToWait ); while( QTime::currentTime() < dieTime ) { QCoreApplication::processEvents( QEventLoop::AllEvents, 100 ); } }