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ę


  • Moderators

    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 zmiennej setPixmap() 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źć.


  • Moderators

    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.



  • Problem rozwiązany. Jedyne co zauważyłem to to, iż pętle przebiegają tak szybko, że pixmapa się nie updatuje (mimo iż jest w kodzie) i widze dopiero nagle efekt końcowy po kilkunastu sekundach. Zrobiłem własną funkcję opóźniającą i wszystko gra. Dziękuję!


  • Moderators

    @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 );
        }
    }
    
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.