QGraphicsItem paint event called continually during QWidget::event loop
-
Hi,
Fair enough. I can't post my exact code for privacy reasons but this is an abstracted version:
mainwindow.hclass MainWindow : public QMainWindow { Q_OBJECT private: Frame* myFrame; };mainwindow.cpp
MainWindow:: MainWindow( QWidget *parent ) : QMainWindow(parent) { setCentralWidget(myFrame); } bool MainWindow:: event( QEvent *event ) { if ( event->type( ) == QEvent::WindowStateChange ) { if ( this->windowState( ).testFlag( Qt::WindowMinimized ) ) { // Tell other windows emit notifyControl_minimizeApplicationWindow( ); LOG(INFO) << "hiding"; return true; } else if ( this->windowState( ).testFlag( Qt::WindowNoState ) ) { emit notifyControl_restoreApplicationWindow( ); LOG(INFO) << "restoring"; return true; } } return QWidget::event( event ); }frame.h
class Frame :public QFrame { Q_OBJECT private: QGraphicsView* myGraphicsView; DiagramScene* myScene; };frame.cpp
Frame:: Frame(MainWindow* parent) { myDiagramScene = new DiagramScene( this ); myGraphicsView = new QGraphicsView( this ); myGraphicsView->setScene( myScene ); }diagramscene.h
class DiagramScene : public QGraphicsScene { Q_OBJECT private: QVector<Rectangle*> myItems; };diagramscene.cpp
DiagramScene:: DiagramScene(Frame* parent) : QGraphicsScene(parent) { //create and add items to the scene here }rectangle.h
class Rectangle : public QGraphicsRectItem { public: int type( ) const Q_DECL_OVERRIDE { return Type; } void updatePosition( ); void paint( QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *widget = 0 ) Q_DECL_OVERRIDE; void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); private: QGraphicsLineItem* myLine; };rectangle.cpp
Rectangle::Rectangle() QGraphicsRectItem() { setLine(); setRectangle(); } void Rectangle:: paint( QPainter *painter, const QStyleOptionGraphicsItem *, QWidget * ) { painter->setPen( this->myColor ); painter->setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing); if ( this->isSelected( ) ) { painter->setPen( QPen( Qt::red, 2 ) ); painter->setBrush( QColor( Qt::red ) ); } else { painter->setPen( QPen( Qt::blue, 2) ); painter->setBrush( QColor( Qt::blue ) ); } painter->drawRect( this->rect( ) ); painter->drawLine( this->myLine->line( ) ); }Hope this helps
Edit - added code tags - p3c0
-
Is it normal that you don't use any layout in your
Frameclass ? -
So now it's working as you want ?
-
No the paint method is still being called repeatedly for each rectangle in the scene, which is time consuming. I only want paint to be called when something changes in the rectangle like when it is moved or the color is changed. It may be that I am misunderstanding when the paint method is triggered. Is it supposed to be triggered at every QWidget event? Because that is what seems to be happening right now.
-
One other detail, you are not calling the correct base class implementation of MainWindow.
Also, do you really need Frame ? Looks like you could put the QGraphicsView directly as central widget, no ?
-
In
MainWindow::event, you are not callingQMainWindow::eventbutQWidget::event. -
What else are you doing in your application ?
-
We have a palette of icons in a dock widget that the user can add into the scene, copy, paste and delete. Each graphics item has a proxy widget that holds properties for the item. The items are rectangles and lines that connect between them so that moving a rectangle should move the lines that are connected to it. I want the items to update at a reasonable event, for example a mouse release event, instead of repeatedly like they doing now which is causing some lag. Basically I want to install an event filter, but am first trying to understand why all QMainWindow events are triggering a graphics item paint.
-
By proxy do you mean you have QProxyGraphicsProxyWidget ?
-
How many are they at once on your scene ?
-
Are you still experiencing that if you avoid the proxy widgets ?
-
Is the code accessible somewhere to be tested ?