Graphics Scene Update



  • Hi,

    I have created a QGraphicsScene and added an ellipse to it and made it movable. Then I wrote a loop where I move the ellipse horizontally on the scene using moveby(x, y) method. But the scene does not change and I only see ellipse at initial location even though the loop completes (the print statement inside the loop executes correct number of time but the ellipse does not move).

    Please suggest how to make ellipse move on screen.


  • Moderators

    @Anurag2904
    show some code to prevent guessing.



  • #include "secondpage.h"
    #include <iostream>
    #include <sstream>
    #include <stdio.h>
    #include <Windows.h>

    secondPage::secondPage(QWidget *parent)
    : QWidget(parent)
    {
    ui.setupUi(this);

    graphicsView = new QGraphicsView(this);
    scene = new QGraphicsScene(this);
    graphicsView->setMinimumSize(1600, 900);
    graphicsView->setSceneRect(0,0, 1600, 900);
    graphicsView->setScene(scene);
    
    //QGraphicsEllipseItem *ellipse; - done in .h file
    ellipse = scene->addEllipse(158,66,20,20, QPen(Qt::black), QBrush(Qt::black));
    ellipse->setFlag(QGraphicsItem::ItemIsMovable);
    
    
    graphicsView->show();
    //SIGNAL TO go back to stacked widget
    connect(this, SIGNAL(callParent(int)), this->parent(), SLOT(newChangePage(int)));
    

    }
    //newRoutine() SLOT is called from stacked widget in a different class
    //#define NUM_OF_WRITES 9U - done is .h file
    void secondPage::newRoutine()
    {

    int i = 0;
    QFile file(fname);
    
    for (; i < NUM_OF_WRITES; i++)
    {
    	int a = i;
    	Sleep(700);
    	if (file.open(QIODevice::Append | QIODevice::Text)) 
    	{
    		QTextStream stream(&file);
    		stream2 << 'Write # ' << i << endl;
    	}
    	else
    	{
    		OutputDebugStringW(L"FAILED TO WRITE");
    		OutputDebugStringW(L"\n");
    	}
    	if ((i == 3) || (i == 6))
    	{
    		ellipse->moveBy(-1280, 360);
    	}
    	else
    	{
    		ellipse->moveBy(640, 0);
    	}
    }
    file.close();
    
    //Go back to stacked widget from where this method was called (see connect above)
    emit callParent(2);
    

    }


    Above is my code. On main screen i have a stacked widget, from there i call newRoutine(). I want to show a animation where ellipse moves around on the graphics view and then trigger a signal - callParent() after which stacked widget will change index to next page.


  • Moderators

    @Anurag2904 Not an answer to your question.

    1. Why do you open the file inside the loop?!
    2. Sleep in a loop in an event driven app (like Qt apps) isn't a good idea - it makes your app unresponsive


  • @Anurag2904 to expand a tiny bit on what @jsulm said,

    you don't give your UI- a chance to update.
    During a function call the UI is not updated, during sleep-calls the ui is not updated. During loops the ui is not updated.

    There are a couple of ways to fix that problem, from "hacky" but very simple over unorthodox but possible, to the correct way but complex for this usecase.

    Which path to you choose?


  • Moderators

    @J.Hilk said in Graphics Scene Update:

    Which path to you choose?

    always teach the clean way ;)



  • So one approach would be this:

    • Create a separate class derived from QObject
    • Create a slot which basically has the code inside your file writing loop
    • Create a QTimer with an interval of 700 ms, and connect it to that slot
    • Every time you enter the slot, you can increment a member variable (which replaces your loop counter)
    • Whenever you want the ellipse to move in a certain fashion, have your class emit a signal. There are different ways to design this, depending on what you want. Probably the closest to your current code would be a signal with a QPointF parameter, which contains the offset by which to move.
    • Connect that signal to a new slot within the class that has access to the ellipse, and have the ellipse move whenever the signal arrives

Log in to reply
 

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