Movement of splitter handle provides inconsistent value to paintEvent
-
Hi! I am making a Plot in which I have two separate Y-Axis which is separated by a vertical QSplitter and a single X-Axis. I plan to do this using QWidget as background and override it's painEvent to create my Plots. To achieve this I create a base QWidget and override it's paintEvent to create X-Axis and then I add a layout on top of it and a vertical QSplitter on top of that, in this I add two more QWidgets to create my Y-Axes by overriding their paintEvent. The problem is that when I move my splitter handle the paintEvent of base QWidget gets a different rect() compared to when I resize my entire window. Here is the code for how I do it:
/* myPlot.h */ #include <QWidget> #include <QPainter> #include <QPaintEvent> #include <QSplitter> #include <QVBoxLayout> class classWidget1; class classWidget2; class myPlot : public QWidget { Q_OBJECT public: myPlot(QWidget *parent); ~myPlot(); classWidget1 *widget1= Q_NULLPTR; classWidget2 *widget2= Q_NULLPTR; protected: void paintEvent(QPaintEvent *event); }; class classWidget1: public QWidget { Q_OBJECT public: classWidget1(QWidget *parent); ~classWidget1(); protected: void paintEvent(QPaintEvent *event); }; class classWidget2: public QWidget { Q_OBJECT public: classWidget2(QWidget *parent); ~classWidget2(); protected: void paintEvent(QPaintEvent *event); };
/* myPlot.cpp */ #include "myPlot.h" myPlot::myPlot(QWidget *parent) : QWidget(parent) { widget1 = new classWidget1(this); // subclass of QWidget widget2 = new classWidget2(this); // subclass of QWidget QVBoxLayout *layout = new QVBoxLayout; QSplitter *mySplitter = new QSplitter(Qt::Vertical); mySplitter->setHandleWidth(2); mySplitter->addWidget(widget1); mySplitter->addWidget(widget2); layout->addWidget(mySplitter); layout->setContentsMargins(0, 5, 0, 50); // Setting the margins for widgets here this->setLayout(layout); } // other constructors and destructors which are all empty void myPlot::paintEvent(QPaintEvent *event) { QRect newRect = event->rect(); // Getting the bounding rectangle int xTop = newRect.x(); int yTop = newRect.y(); int xBtm = newRect.width() - 1; // decrease width by 1 because otherwise it is outside and does not show int yBtm = newRect.height() - 1; // same situation as width above QPainter painterPlot(this); // my Painter painterPlot.drawRect(xTop, yTop, xBtm, yBtm); // Drawing bounding rect // Drawing a green line for demonstration purpose QPen myPen(Qt::green); myPen.setWidth(2); painterPlot.setPen(myPen); painterPlot.drawLine(xTop, yBtm - 10, xBtm, yBtm - 10); // Drawing a red line for demonstration purpose QPen myPen2(Qt::red); myPen2.setWidth(2); painterPlot.setPen(myPen2); painterPlot.drawLine(xTop, yBtm - 20, xBtm, yBtm - 20); } void classWidget1::paintEvent(QPaintEvent *event) { QRect newRect = event->rect(); // bounding rect // width of drawn rectangle will be smaller than width of bounding rect int xTop = newRect.x()+5; int xBtm = newRect.width() - 11; // Height of drawn rectangle will be same as height of bounding rect int yTop = newRect.y(); int yBtm = newRect.height() - 1; QPainter painterWidget1(this); painterWidget1.drawRect(xTop, yTop, xBtm, yBtm); // drawn rectangle painterWidget1.drawText(50, 50, "Widget 1"); // text for identification } void classWidget2::paintEvent(QPaintEvent *event) { QRect newRect = event->rect(); // bounding rect // width of drawn rectangle will be smaller than width of bounding rect int xTop = newRect.x()+5; int xBtm = newRect.width() - 11; // Height of drawn rectangle will be same as height of bounding rect int yTop = newRect.y(); int yBtm = newRect.height() - 1; QPainter painterWidget2(this); painterWidget2.drawRect(xTop, yTop, xBtm, yBtm); // drawn rectangle painterWidget2.drawText(50, 50, "Widget 2"); // text for identification }
It looks like this:
I checked using qDebug(), when I move the splitter the value of rect() received by the paintEvent() of myPlot class is not the bounding rect of the widget but it is approximately the bounding rect of the layout (I guess), which causes it to draw the red and green lines according to layout. However, on resize the bounding rect is again the original bounding rect of base widget and so it draws the lines correctly. How can I remedy this situation? Is there any way I can take complete control of paintEvent() and update it only manually?
-
Hi
You uses QPaintEvent rect() which is the dirty rect. ( area that needs repaint)
What happens if you use only
QRect newRect = rect();
so you take the widgets full rect ? -
Hi
You uses QPaintEvent rect() which is the dirty rect. ( area that needs repaint)
What happens if you use only
QRect newRect = rect();
so you take the widgets full rect ?