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. Movement of splitter handle provides inconsistent value to paintEvent
Forum Updated to NodeBB v4.3 + New Features

Movement of splitter handle provides inconsistent value to paintEvent

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 251 Views 2 Watching
  • 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.
  • CJhaC Offline
    CJhaC Offline
    CJha
    wrote on last edited by
    #1

    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:
    Layout_all.png

    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?

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      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 ?

      CJhaC 1 Reply Last reply
      3
      • mrjjM mrjj

        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 ?

        CJhaC Offline
        CJhaC Offline
        CJha
        wrote on last edited by
        #3

        @mrjj Thank you! It solved my problem :)

        1 Reply Last reply
        1

        • Login

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