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
Forum Updated to NodeBB v4.3 + New Features

paintEvent is not painting complete objects

Scheduled Pinned Locked Moved Unsolved General and Desktop
qpainterqpaintevent
11 Posts 4 Posters 6.0k 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.
  • N Offline
    N Offline
    NIXIN
    wrote on 5 Sept 2016, 06:26 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?

    R 1 Reply Last reply 5 Sept 2016, 06:37
    0
    • N NIXIN
      5 Sept 2016, 06:26

      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?

      R Offline
      R Offline
      raven-worx
      Moderators
      wrote on 5 Sept 2016, 06:37 last edited by raven-worx 9 May 2016, 06:39
      #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
      • N Offline
        N Offline
        NIXIN
        wrote on 5 Sept 2016, 06:42 last edited by
        #3

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

        R 1 Reply Last reply 5 Sept 2016, 06:50
        0
        • N NIXIN
          5 Sept 2016, 06:42

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

          R Offline
          R Offline
          raven-worx
          Moderators
          wrote on 5 Sept 2016, 06:50 last edited by raven-worx 9 May 2016, 06:51
          #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
          • N Offline
            N Offline
            NIXIN
            wrote on 5 Sept 2016, 06:54 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();
            

            }

            R 1 Reply Last reply 5 Sept 2016, 06:55
            0
            • N NIXIN
              5 Sept 2016, 06:54

              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();
              

              }

              R Offline
              R Offline
              raven-worx
              Moderators
              wrote on 5 Sept 2016, 06:55 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
              • N Offline
                N Offline
                NIXIN
                wrote on 5 Sept 2016, 07:00 last edited by
                #7

                Can you please provide a small code

                R 1 Reply Last reply 5 Sept 2016, 07:12
                0
                • N NIXIN
                  5 Sept 2016, 07:00

                  Can you please provide a small code

                  R Offline
                  R Offline
                  raven-worx
                  Moderators
                  wrote on 5 Sept 2016, 07:12 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 5 Sept 2016, 07:39 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
                    • V Offline
                      V Offline
                      VRonin
                      wrote on 5 Sept 2016, 09:08 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 5 Sept 2016, 09:41
                      0
                      • V VRonin
                        5 Sept 2016, 09:08

                        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 5 Sept 2016, 09:41 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

                        5/11

                        5 Sept 2016, 06:54

                        • Login

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