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. paintEvent is not painting complete objects

paintEvent is not painting complete objects

Scheduled Pinned Locked Moved Unsolved General and Desktop
qpainterqpaintevent
11 Posts 4 Posters 6.0k 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.
  • NIXINN Offline
    NIXINN Offline
    NIXIN
    wrote on last edited by
    #1

    I am trying this piece of code below:

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H

    #include <QWidget>
    #include <QLabel>
    #include <QPainter>

    namespace Ui {
    class Widget;
    }

    class Widget : public QWidget
    {
    Q_OBJECT

    public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    void paintEvent(QPaintEvent *e);
    void operation();
    void drawLabel();
    
    int flag = 0;
    int startX, startY;
    QString labelText;
    

    private:
    Ui::Widget *ui;
    };

    #endif // WIDGET_H

    widget.cpp

    #include "widget.h"
    #include "ui_widget.h"

    Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
    {
    ui->setupUi(this);
    }

    Widget::~Widget()
    {
    delete ui;
    }

    void Widget::paintEvent(QPaintEvent *e)
    {
    QPainter *painter = new QPainter(this);
    if(flag == 1)
    {
    painter->setPen(QPen(Qt::black, 1));
    painter->drawLine(startX, startY, startX+30, startY);
    painter->drawLine(startX+50, startY, startX+80, startY);
    drawLabel();
    }
    }

    void Widget::drawLabel()
    {
    QLabel *label = new QLabel(this);
    label->setStyleSheet("border: 1px solid black");
    label->setGeometry(startX+30, startY-10, 20, 20);
    label->setText(labelText);
    label->show();
    }

    void Widget::operation()
    {
    int found = 1;

    if(found)
    {
        labelText = "2";
        startX = 20;
        startY = 50;
        flag = 1;
        update();
    
        labelText = "3";
        startX = 100;
        startY = 50;
        flag = 1;
        update();
    }
    

    }

    main.cpp

    #include "widget.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    Widget w;
    w.operation();
    w.show();

    return a.exec();
    

    }

    I want to draw a label between two lines side by side, but when I run the above code label with labelText 3, between two lines is visible. labelText 2, between two lines is not painted. I don,t understand why? Can anybody help me to solve this?

    raven-worxR 1 Reply Last reply
    0
    • NIXINN NIXIN

      I am trying this piece of code below:

      widget.h

      #ifndef WIDGET_H
      #define WIDGET_H

      #include <QWidget>
      #include <QLabel>
      #include <QPainter>

      namespace Ui {
      class Widget;
      }

      class Widget : public QWidget
      {
      Q_OBJECT

      public:
      explicit Widget(QWidget *parent = 0);
      ~Widget();

      void paintEvent(QPaintEvent *e);
      void operation();
      void drawLabel();
      
      int flag = 0;
      int startX, startY;
      QString labelText;
      

      private:
      Ui::Widget *ui;
      };

      #endif // WIDGET_H

      widget.cpp

      #include "widget.h"
      #include "ui_widget.h"

      Widget::Widget(QWidget *parent) :
      QWidget(parent),
      ui(new Ui::Widget)
      {
      ui->setupUi(this);
      }

      Widget::~Widget()
      {
      delete ui;
      }

      void Widget::paintEvent(QPaintEvent *e)
      {
      QPainter *painter = new QPainter(this);
      if(flag == 1)
      {
      painter->setPen(QPen(Qt::black, 1));
      painter->drawLine(startX, startY, startX+30, startY);
      painter->drawLine(startX+50, startY, startX+80, startY);
      drawLabel();
      }
      }

      void Widget::drawLabel()
      {
      QLabel *label = new QLabel(this);
      label->setStyleSheet("border: 1px solid black");
      label->setGeometry(startX+30, startY-10, 20, 20);
      label->setText(labelText);
      label->show();
      }

      void Widget::operation()
      {
      int found = 1;

      if(found)
      {
          labelText = "2";
          startX = 20;
          startY = 50;
          flag = 1;
          update();
      
          labelText = "3";
          startX = 100;
          startY = 50;
          flag = 1;
          update();
      }
      

      }

      main.cpp

      #include "widget.h"
      #include <QApplication>

      int main(int argc, char *argv[])
      {
      QApplication a(argc, argv);
      Widget w;
      w.operation();
      w.show();

      return a.exec();
      

      }

      I want to draw a label between two lines side by side, but when I run the above code label with labelText 3, between two lines is visible. labelText 2, between two lines is not painted. I don,t understand why? Can anybody help me to solve this?

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @NIXIN
      you are doing multiple mistakes in your code.

      1. you are creating widgets on every paintEvent call! This is very bad design.
      2. in your Widget::operation() you update your data and call update() to immediately set the data again and call update() again. You should know that update() schedules a paint-event, where multiple calls to update() still result in a single paint-event (in the next event loop iteration). So it doesn't repaint immediately. There is a repaint() method for this, but as i said you already have a bad design by creating widgets on every paintEvent call.

      You should draw the text using QPainter instead creating a QLabel every time. But still the label text "2" would never be rendered, since you immediately overwrite it afterwards.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • NIXINN Offline
        NIXINN Offline
        NIXIN
        wrote on last edited by
        #3

        can you provide a small piece of code, how to do it?

        raven-worxR 1 Reply Last reply
        0
        • NIXINN NIXIN

          can you provide a small piece of code, how to do it?

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by raven-worx
          #4

          @NIXIN

          void Widget::paintEvent(QPaintEvent *e)
          {
              QPainter painter(this);  // do create the painter on the stack
              ....
              drawLabel( p );
          }
          
          void Widget::drawLabel(QPainter & p)
          {
          QRect rect(startX+30, startY-10, 20, 20);
          p.setPen( QPen::QPen(Qt::black, 1.0, Qt::SolidLine) );
          p.setBrush( Qtt::NoBrush );
          p.drawRect( rect );
          p.drawText( rect, Qt::AlignCenter, labelText );
          }
          

          But as i said, this only draws the last label text set. You should store your data (position, label text,...) in a list (and call update() once). And draw each using drawLabel() for example.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          1
          • NIXINN Offline
            NIXINN Offline
            NIXIN
            wrote on last edited by
            #5

            That's fine, what I want to know is how to not delete the drawing from previous paintevent,
            because as per your statement:
            " But still the label text "2" would never be rendered, since you immediately overwrite it afterwards."
            I want to keep the drawing for both:

            if(found)
            {
            labelText = "2";
            startX = 20;
            startY = 50;
            flag = 1;
            update();

            labelText = "3";
            startX = 100;
            startY = 50;
            flag = 1;
            update();
            

            }

            raven-worxR 1 Reply Last reply
            0
            • NIXINN NIXIN

              That's fine, what I want to know is how to not delete the drawing from previous paintevent,
              because as per your statement:
              " But still the label text "2" would never be rendered, since you immediately overwrite it afterwards."
              I want to keep the drawing for both:

              if(found)
              {
              labelText = "2";
              startX = 20;
              startY = 50;
              flag = 1;
              update();

              labelText = "3";
              startX = 100;
              startY = 50;
              flag = 1;
              update();
              

              }

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              @NIXIN
              as i said store your data (e.g. struct) in a list and draw each item separately while iterating over the list in the paintEvent()

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0
              • NIXINN Offline
                NIXINN Offline
                NIXIN
                wrote on last edited by
                #7

                Can you please provide a small code

                raven-worxR 1 Reply Last reply
                0
                • NIXINN NIXIN

                  Can you please provide a small code

                  raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by
                  #8

                  @NIXIN
                  come on thats not that hard...

                  struct Data {
                      Data(QString t, int x, int y, int f)
                           : labelText(t), startX(x), startY(y), flag(f)
                      {
                      }
                  
                      QString labelText;;
                      int startX;;
                      int startY;
                      int flag;
                  }
                  QList<Data> dataList;
                  ...
                  void Widget::operation()
                  {
                  int found = 1;
                  
                  if(found)
                  {
                      dataList.clear();
                  
                      dataList << Data("2", 20, 50, 1);
                      dataList << Data("3", 100, 50, 1);
                      update();
                  }
                  
                  }
                  
                  void Widget::paintEvent(QPaintEvent *e)
                  {
                      QPainter painter(this);  // do create the painter on the stack
                      ....
                      foreach( Data d, dataList )
                           drawLabel( p, data );
                  }
                  
                  void Widget::drawLabel(QPainter & p, const Data & d)
                  {
                  QRect rect(d.startX+30, d.startY-10, 20, 20);
                  p.setPen( QPen::QPen(Qt::black, 1.0, Qt::SolidLine) );
                  p.setBrush( Qt::NoBrush );
                  p.drawRect( rect );
                  p.drawText( rect, Qt::AlignCenter, d.labelText );
                  }
                  

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  1 Reply Last reply
                  3
                  • J Offline
                    J Offline
                    Jan-Willem
                    wrote on last edited by
                    #9

                    Perhaps this might be also useful?

                    http://www.cplusplus.com/doc/tutorial/structures/

                    http://doc.qt.io/qt-5/qlist.html

                    1 Reply Last reply
                    0
                    • VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by
                      #10

                      How about composing the widget instead of painting it.
                      Put two QFrame with a HLine style and a label in a QVBoxLayout. So much easier!

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      J 1 Reply Last reply
                      0
                      • VRoninV VRonin

                        How about composing the widget instead of painting it.
                        Put two QFrame with a HLine style and a label in a QVBoxLayout. So much easier!

                        J Offline
                        J Offline
                        Jan-Willem
                        wrote on last edited by
                        #11

                        @VRonin Depends on what he wants to achieve.
                        Is it a widget, than I agree with you.
                        Is it some CAD-drawing (looks like a diagram symbol to me), then I would prefer drawing.
                        For the latter the Graphics View Framework would be more practical though.

                        1 Reply Last reply
                        0

                        • Login

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