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. How to draw something with QPainter when the button is pushed

How to draw something with QPainter when the button is pushed

Scheduled Pinned Locked Moved Solved General and Desktop
qpainterevent handling
3 Posts 2 Posters 2.5k 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
    TrueNova
    wrote on 6 May 2020, 23:02 last edited by
    #1

    I am working on my project from programming and I need to draw, for example, a circle every time the pushButton is pressed using QPainter. This is the first problem, and the second one here is that I need some information to be sent to the drawing function too, for example, int vector, and being able to draw so many circles, as there are elements in the vector with radii of the elements itself. I have found some code based on signals and slots.
    The sender:

    public:
        Listener(QObject *p = 0) : QObject(p) {
            QTimer * t = new QTimer(this);
            t->setInterval(200);
            connect(t, SIGNAL(timeout()), this, SLOT(sendData()));
            t->start();
        }
    signals:
        void dataAvaiable(int, int);
    
    public slots:
        void sendData() {
            emit dataAvaiable(qrand() % 200, qrand() % 200);
        }
    

    The reciever:

        void receiveData(int x, int y) {
            QPainter painter(this);
            QPen pen(Qt::white, 5);
            painter.setRenderHint(QPainter::HighQualityAntialiasing);
            painter.setPen(pen);
            QPoint point(x, y);
            painter.drawEllipse(x, y, 100, 100);
            data.append(point);
        }
    

    The connection itself in main.cpp

    QObject::connect(&l, SIGNAL(dataAvaiable(int,int)), &w, SLOT(receiveData(int,int)));
    

    But the code doesn't suit for my exact task with buttons and doesn't even want to draw anythig, just any circle at all. Howewer, in debugger the code executes properly, and I am relatively new to Qt and C++ so I can't figure out by myself, where the problem is and how to solve my task.
    Can someone please do a minimal of code or simply explain to me, where exactly the problem is? Need to solve the problem as soon as possible. Thank you.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SamurayH
      wrote on 7 May 2020, 00:26 last edited by SamurayH 5 Jul 2020, 00:27
      #2

      From the QPainter class description:

      Warning: When the paintdevice is a widget, QPainter can only be used inside a 
      paintEvent() function or in a function called by paintEvent().
      

      You can force calling paintEvent() by invoking update() , so you must connect the onclicked() signal of your button to the update() slot of the widget you're drawing on.

      For your second problem, the data can be a member variable.
      Here's an example:

      // mywidget.h
      #include <QVector>
      #include <QPoint>
      // other includes and the constructor...
      protected:
          virtual void paintEvent(QPaintEvent *event);
      
      private slots:
          void onButtonClicked();
      
      private:
          QPushButton* mButton;
          QVector<QPoint> mCirclesData;
      
      // mywidget.cpp
      
      MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
      {
          mButton = new QPushButton(this);
         // customise your button...
          connect(mButton, &QPushButton::clicked, this, &MyWidget::onButtonClicked); 
      }
      
      //...
      void MyWidget::onButtonClicked(){
          int x = qrand() % 200, y = x;
          mCirclesData << QPoint(x,y); 
          update(); // force calling paintEvent
      }
      
      void MyWidget::paintEvent(QPaintEvent *event)
      {
           QPainter painter(this);
           QPen pen(Qt::white, 5);
           painter.setRenderHint(QPainter::HighQualityAntialiasing);
           painter.setPen(pen);     
           painter.drawEllipse(mCirclesData.last().x(), mCirclesData.last().y(), 100, 100);
      }
      

      As you can see the "data" is added to the array before being used to draw the circles...Anyway, I hope you got the idea.

      "قال رسول الله صلى الله عليه وسلم : " أحب الناس إلى الله أنفعهم للناس

      T 1 Reply Last reply 7 May 2020, 07:28
      1
      • S SamurayH
        7 May 2020, 00:26

        From the QPainter class description:

        Warning: When the paintdevice is a widget, QPainter can only be used inside a 
        paintEvent() function or in a function called by paintEvent().
        

        You can force calling paintEvent() by invoking update() , so you must connect the onclicked() signal of your button to the update() slot of the widget you're drawing on.

        For your second problem, the data can be a member variable.
        Here's an example:

        // mywidget.h
        #include <QVector>
        #include <QPoint>
        // other includes and the constructor...
        protected:
            virtual void paintEvent(QPaintEvent *event);
        
        private slots:
            void onButtonClicked();
        
        private:
            QPushButton* mButton;
            QVector<QPoint> mCirclesData;
        
        // mywidget.cpp
        
        MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
        {
            mButton = new QPushButton(this);
           // customise your button...
            connect(mButton, &QPushButton::clicked, this, &MyWidget::onButtonClicked); 
        }
        
        //...
        void MyWidget::onButtonClicked(){
            int x = qrand() % 200, y = x;
            mCirclesData << QPoint(x,y); 
            update(); // force calling paintEvent
        }
        
        void MyWidget::paintEvent(QPaintEvent *event)
        {
             QPainter painter(this);
             QPen pen(Qt::white, 5);
             painter.setRenderHint(QPainter::HighQualityAntialiasing);
             painter.setPen(pen);     
             painter.drawEllipse(mCirclesData.last().x(), mCirclesData.last().y(), 100, 100);
        }
        

        As you can see the "data" is added to the array before being used to draw the circles...Anyway, I hope you got the idea.

        T Offline
        T Offline
        TrueNova
        wrote on 7 May 2020, 07:28 last edited by
        #3

        @SamurayH The solution is perfect to me. Thank you very much!

        1 Reply Last reply
        0

        3/3

        7 May 2020, 07:28

        • Login

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