Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Incorrect exposedRect in QGraphicsWidget::paint()
QtWS25 Last Chance

Incorrect exposedRect in QGraphicsWidget::paint()

Scheduled Pinned Locked Moved General and Desktop
qgraphicswidgetexposedrect
2 Posts 2 Posters 1.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Tereius
    wrote on 29 May 2015, 18:27 last edited by
    #1

    Hi,

    In my application I have multiple, rather big custom GraphicsWidgets (derived from QGraphicsWidget). To speed up drawing I fall back on QStyleOptionGraphicsItem::exposedRect in my QGraphicsWidget::paint() reimplementations. If the GraphicsWidgets are managed by a QGraphicsLayout or positioned manually via setGeometry() the exposedRect provides wrong size information under certain conditions. Here is a minimal example that should illustrate the problem:

    The QGraphicsView shows three Bar objects. In the paint() function of the Bar objects only the exposedRect is drawn (for every paint() invocation the colour is toggled).
    Every Bar obj. grows in its height by one pixel if the appropriate button is clicked.
    If the topmost button is clicked everything works as expected (boundingRect equals exposedRect in every paint() call):
    alt text

    If the second button is clicked the exposedRect of the first Bar realigns to QRectF(0,49 382x2) although the first Bar should be fully visible (geometry: QRectF(9,9 382x51)). The third button triggers the same glitch for the second Bar.
    I don't understand why exposedRect shows this behaviour. Can someone clarify?
    alt text
    I've tested with:
    Qt5.4.1 MSVC2013 OpenGL 32Bit
    Qt5.3.2 MSVC2013 OpenGL 32Bit
    Best Regards

    minimal.h
    #include <QGraphicsItem>
    #include <QGraphicsWidget>
    #include <QGraphicsScene>
    #include <QGraphicsLinearLayout>
    #include <QStyleOptionGraphicsItem>
    #include <QGridLayout>
    #include <QPushButton>
    #include <QWidget>
    
    class Bar : public QGraphicsWidget {
    
    	Q_OBJECT
    
    public:
    	Bar(QPushButton *pButton, QGraphicsItem *pParent = 0) : QGraphicsWidget(pParent), mToggleColor(false) {
    
    		setFlag(QGraphicsItem::ItemUsesExtendedStyleOption);
    		setMinimumSize(100., 20.);
    		connect(pButton, SIGNAL(clicked()), this, SLOT(Grow()));
    	}
    	virtual ~Bar() {}
    	void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget *pWidget = 0) {
    
    		const QRectF exposed_rect = pOption->exposedRect;
    		QPen pen;
    		pen.setColor(Qt::magenta);
    		pen.setWidth(1);
    		pPainter->save();
    		pPainter->setPen(pen);
    		if(mToggleColor)pPainter->fillRect(exposed_rect, Qt::green);
    		else pPainter->fillRect(exposed_rect, Qt::yellow);
    		QRectF border_rect = exposed_rect;
    		border_rect.setHeight(border_rect.height() - 1);
    		border_rect.setWidth(border_rect.width() - 1);
    		pPainter->drawRect(exposed_rect);
    		mToggleColor = !mToggleColor;
    		pPainter->restore();
    	}
    
    	public slots:
    	void Grow() {
    
    		int old_height = boundingRect().height();
    		setMinimumHeight(old_height + 1);
    	}
    
    private:
    	bool mToggleColor;
    };
    

    main.cpp
    #include "minimal.h"
    #include <QApplication>
    #include <QGraphicsView>
    #include <QGraphicsItem>
    #include <QGraphicsWidget>
    #include <QGraphicsScene>
    #include <QGraphicsLinearLayout>
    #include <QStyleOptionGraphicsItem>
    #include <QGridLayout>
    #include <QPushButton>
    #include <QWidget>
    
    
    int main(int argc, char *argv[]) {
    	QApplication app(argc, argv);
    
    	QWidget widget;
    
    	QGraphicsScene scene;
    
    	QGraphicsWidget *p_graphics_widget = new QGraphicsWidget(0, Qt::Window);
    	p_graphics_widget->setGeometry(20, 50, 400, 500);
    
    	QPushButton *p_button_one = new QPushButton("Grow one", &widget);
    	QPushButton *p_button_two = new QPushButton("Grow two", &widget);
    	QPushButton *p_button_three = new QPushButton("Grow three", &widget);
    
    	Bar *p_bar_one = new Bar(p_button_one, p_graphics_widget);
    	Bar *p_bar_two = new Bar(p_button_two, p_graphics_widget);
    	Bar *p_bar_three = new Bar(p_button_three, p_graphics_widget);
    
    	QGraphicsLinearLayout *p_graphics_layout = new QGraphicsLinearLayout(Qt::Vertical);
    	p_graphics_layout->setSpacing(0.);
    	p_graphics_layout->addItem(p_bar_one);
    	p_graphics_layout->addItem(p_bar_two);
    	p_graphics_layout->addItem(p_bar_three);
    	p_graphics_layout->addStretch(99);
    	p_graphics_widget->setLayout(p_graphics_layout);
    
    	scene.addItem(p_graphics_widget);
    	scene.setBackgroundBrush(Qt::white);
    	scene.setSceneRect(scene.itemsBoundingRect());
    
    	QGraphicsView view(&scene);
    
    	QGridLayout *p_layout = new QGridLayout();
    	p_layout->addWidget(&view, 0, 0);
    	p_layout->addWidget(p_button_one, 1, 0);
    	p_layout->addWidget(p_button_two, 2, 0);
    	p_layout->addWidget(p_button_three, 3, 0);
    	widget.setLayout(p_layout);
    
    	widget.show();
    	view.show();
    	return app.exec();
    }
    
    1 Reply Last reply
    0
    • L Offline
      L Offline
      LuGRU
      wrote on 31 May 2015, 13:36 last edited by
      #2

      Keep Your drawing inside boundingRect() or in Your case exposed area. Probably in this case this will be the same for parent widget interaction i.e. mowing widget but will change when painting separate elements inside .

      Anyway issue is with Your drawing of border.
      alt text

              QRectF border_rect = exposed_rect;
              border_rect.adjust( pen.widthF(), pen.widthF(), -pen.widthF(), -pen.widthF());
              pPainter->drawRect(border_rect);
      

      Zoom in image to see that each rectangle is inside boundingbox().

      1 Reply Last reply
      0

      1/2

      29 May 2015, 18:27

      • Login

      • Login or register to search.
      1 out of 2
      • First post
        1/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved