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

Draw in QPainter

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 4 Posters 1.1k Views 1 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.
  • ODБOïO ODБOï

    hi @sierdzio
    that is the first test thing i did, yes.

    but if i create one QPainter on the stack it is deleted every time

    i want to keep the old path picture and add new line to it

    J.HilkJ Online
    J.HilkJ Online
    J.Hilk
    Moderators
    wrote on last edited by
    #4

    @LeLev Why don't you then simply append the new lines to a member QVector and simply call drawLines(vector) inside the paint event?


    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


    Q: What's that?
    A: It's blue light.
    Q: What does it do?
    A: It turns blue.

    1 Reply Last reply
    1
    • ODБOïO ODБOï

      hi @sierdzio
      that is the first test thing i did, yes.

      but if i create one QPainter on the stack it is deleted every time

      i want to keep the old path picture and add new line to it

      sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #5

      @LeLev said in Draw in QPainter:

      hi @sierdzio
      that is the first test thing i did, yes.

      but if i create one QPainter on the stack it is deleted every time

      i want to keep the old path picture and add new line to it

      Then at the end of paint event, save the painter to a picture (QPixmap). Then in next paint event, first paint the pixmap, then add your new line to it (and save another pixmap).

      (Z(:^

      1 Reply Last reply
      1
      • sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #6

        Perhaps you can work around this by using member pointer like you do, but then calling QPainter::begin() in the beginning of your event handler. I'm not sure if it will work, though.

        (Z(:^

        ODБOïO 1 Reply Last reply
        1
        • sierdzioS sierdzio

          Perhaps you can work around this by using member pointer like you do, but then calling QPainter::begin() in the beginning of your event handler. I'm not sure if it will work, though.

          ODБOïO Offline
          ODБOïO Offline
          ODБOï
          wrote on last edited by ODБOï
          #7

          @J-Hilk i will try,
          but that means every time you add a new line, you re-draw all the lines in the vector (from the beginning) ?

          @sierdzio
          like this, the first line is drawn and then a crash.

            void paintEvent(QPaintEvent *event)
              {
                  Q_UNUSED(event)
                  if(!painter->isActive()){
                   painter->begin(this);
                  }
                  drawLineW(qrand()*100, qrand()*100,(qrand()%10 > 5)?true:false);
              }
          

          is there an other type that will not clear the screen, and i can simply add lines ? im not forced to use QPainter

          jsulmJ 1 Reply Last reply
          0
          • ODБOïO ODБOï

            @J-Hilk i will try,
            but that means every time you add a new line, you re-draw all the lines in the vector (from the beginning) ?

            @sierdzio
            like this, the first line is drawn and then a crash.

              void paintEvent(QPaintEvent *event)
                {
                    Q_UNUSED(event)
                    if(!painter->isActive()){
                     painter->begin(this);
                    }
                    drawLineW(qrand()*100, qrand()*100,(qrand()%10 > 5)?true:false);
                }
            

            is there an other type that will not clear the screen, and i can simply add lines ? im not forced to use QPainter

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #8

            @LeLev said in Draw in QPainter:

            you re-draw all the lines in the vector (from the beginning) ?

            You can draw in a QImage when you add a line and draw the image in paintEvent

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            ODБOïO 1 Reply Last reply
            2
            • jsulmJ jsulm

              @LeLev said in Draw in QPainter:

              you re-draw all the lines in the vector (from the beginning) ?

              You can draw in a QImage when you add a line and draw the image in paintEvent

              ODБOïO Offline
              ODБOïO Offline
              ODБOï
              wrote on last edited by ODБOï
              #9

              hi
              @jsulm said in Draw in QPainter:

              You can draw in a QImage

              sorry i can't find methods to draw in a QImage nor in QPaintDevice

              i have to pass the image to my QPainter so i can draw right ?

              #ifndef MAINWINDOW_H
              #define MAINWINDOW_H
              
              #include <QMainWindow>
              #include <QPainter>
              #include <QTimer>
              #include <QVector>
              #include <QDebug>
              
              QT_BEGIN_NAMESPACE
              namespace Ui { class MainWindow; }
              QT_END_NAMESPACE
              
              class MainWindow : public QMainWindow
              {
                  Q_OBJECT
              
              public:
                  MainWindow(QWidget *parent = nullptr);
                  ~MainWindow();
              protected:
                  void paintEvent(QPaintEvent *event)
                  {
                      Q_UNUSED(event)
                      if(!painter->isActive()){
                       painter->begin(this);
                      }
              
                      drawLineW(qrand()*100, qrand()*100,(qrand()%10 > 5)?true:false);
                  }
              
                  void drawLineW(int x, int y, bool down){
                     
                      painter->drawLine(lastX,lastY,x,y);
                      lastX = x;
                      lastY = y;
                  }
              
              private:
                  int lastX=0;
                  int lastY=0;
                  //QVector <QPoint> lines; 
                  QImage pathImg;
              
                  QPainter* painter;
                  QTimer * drawTimer;
                  Ui::MainWindow *ui;
              };
              #endif // MAINWINDOW_H
              
              //__________________________________
              MainWindow::MainWindow(QWidget *parent)
                  : QMainWindow(parent)
                  , ui(new Ui::MainWindow)
              {
                  ui->setupUi(this);
              
                  drawTimer = new QTimer(this);
              
                  painter = new QPainter(&pathImg);
              
                  drawTimer->setInterval(100);
              
                  QObject::connect(drawTimer,&QTimer::timeout,[=](){
              
                      update();
                  });
              
                  drawTimer->start();
              
              }
              
              

              sorry im struggling so hard now, i can't get this done fo 3 houres.. I m not used to QWidgets at all.
              i did the same thing in qml/js in about 10minutes

              sierdzioS jsulmJ 2 Replies Last reply
              0
              • ODБOïO ODБOï

                hi
                @jsulm said in Draw in QPainter:

                You can draw in a QImage

                sorry i can't find methods to draw in a QImage nor in QPaintDevice

                i have to pass the image to my QPainter so i can draw right ?

                #ifndef MAINWINDOW_H
                #define MAINWINDOW_H
                
                #include <QMainWindow>
                #include <QPainter>
                #include <QTimer>
                #include <QVector>
                #include <QDebug>
                
                QT_BEGIN_NAMESPACE
                namespace Ui { class MainWindow; }
                QT_END_NAMESPACE
                
                class MainWindow : public QMainWindow
                {
                    Q_OBJECT
                
                public:
                    MainWindow(QWidget *parent = nullptr);
                    ~MainWindow();
                protected:
                    void paintEvent(QPaintEvent *event)
                    {
                        Q_UNUSED(event)
                        if(!painter->isActive()){
                         painter->begin(this);
                        }
                
                        drawLineW(qrand()*100, qrand()*100,(qrand()%10 > 5)?true:false);
                    }
                
                    void drawLineW(int x, int y, bool down){
                       
                        painter->drawLine(lastX,lastY,x,y);
                        lastX = x;
                        lastY = y;
                    }
                
                private:
                    int lastX=0;
                    int lastY=0;
                    //QVector <QPoint> lines; 
                    QImage pathImg;
                
                    QPainter* painter;
                    QTimer * drawTimer;
                    Ui::MainWindow *ui;
                };
                #endif // MAINWINDOW_H
                
                //__________________________________
                MainWindow::MainWindow(QWidget *parent)
                    : QMainWindow(parent)
                    , ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                
                    drawTimer = new QTimer(this);
                
                    painter = new QPainter(&pathImg);
                
                    drawTimer->setInterval(100);
                
                    QObject::connect(drawTimer,&QTimer::timeout,[=](){
                
                        update();
                    });
                
                    drawTimer->start();
                
                }
                
                

                sorry im struggling so hard now, i can't get this done fo 3 houres.. I m not used to QWidgets at all.
                i did the same thing in qml/js in about 10minutes

                sierdzioS Offline
                sierdzioS Offline
                sierdzio
                Moderators
                wrote on last edited by
                #10

                @LeLev said in Draw in QPainter:

                i have to pass the image to my QPainter so i can draw right ?

                You can use setBackground() or drawPixmap() first, then proceed with your drawLine() call.

                (Z(:^

                ODБOïO 1 Reply Last reply
                0
                • ODБOïO ODБOï

                  hi
                  @jsulm said in Draw in QPainter:

                  You can draw in a QImage

                  sorry i can't find methods to draw in a QImage nor in QPaintDevice

                  i have to pass the image to my QPainter so i can draw right ?

                  #ifndef MAINWINDOW_H
                  #define MAINWINDOW_H
                  
                  #include <QMainWindow>
                  #include <QPainter>
                  #include <QTimer>
                  #include <QVector>
                  #include <QDebug>
                  
                  QT_BEGIN_NAMESPACE
                  namespace Ui { class MainWindow; }
                  QT_END_NAMESPACE
                  
                  class MainWindow : public QMainWindow
                  {
                      Q_OBJECT
                  
                  public:
                      MainWindow(QWidget *parent = nullptr);
                      ~MainWindow();
                  protected:
                      void paintEvent(QPaintEvent *event)
                      {
                          Q_UNUSED(event)
                          if(!painter->isActive()){
                           painter->begin(this);
                          }
                  
                          drawLineW(qrand()*100, qrand()*100,(qrand()%10 > 5)?true:false);
                      }
                  
                      void drawLineW(int x, int y, bool down){
                         
                          painter->drawLine(lastX,lastY,x,y);
                          lastX = x;
                          lastY = y;
                      }
                  
                  private:
                      int lastX=0;
                      int lastY=0;
                      //QVector <QPoint> lines; 
                      QImage pathImg;
                  
                      QPainter* painter;
                      QTimer * drawTimer;
                      Ui::MainWindow *ui;
                  };
                  #endif // MAINWINDOW_H
                  
                  //__________________________________
                  MainWindow::MainWindow(QWidget *parent)
                      : QMainWindow(parent)
                      , ui(new Ui::MainWindow)
                  {
                      ui->setupUi(this);
                  
                      drawTimer = new QTimer(this);
                  
                      painter = new QPainter(&pathImg);
                  
                      drawTimer->setInterval(100);
                  
                      QObject::connect(drawTimer,&QTimer::timeout,[=](){
                  
                          update();
                      });
                  
                      drawTimer->start();
                  
                  }
                  
                  

                  sorry im struggling so hard now, i can't get this done fo 3 houres.. I m not used to QWidgets at all.
                  i did the same thing in qml/js in about 10minutes

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #11

                  @LeLev said in Draw in QPainter:

                  sorry i can't find methods to draw in a QImage

                  Sorry, it's drawPixmap.

                  "i have to pass the image to my QPainter so i can draw right ?" - no, use one of the drawPixmap() methods..

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  1
                  • sierdzioS sierdzio

                    @LeLev said in Draw in QPainter:

                    i have to pass the image to my QPainter so i can draw right ?

                    You can use setBackground() or drawPixmap() first, then proceed with your drawLine() call.

                    ODБOïO Offline
                    ODБOïO Offline
                    ODБOï
                    wrote on last edited by
                    #12

                    @sierdzio

                    i call begin() as you suggested
                    and i also have to call end() at the end of my method.

                    now i can see my randomly generated lines, but every time i add a line the rest of lines are deleted/cleaned.

                    @sierdzio said in Draw in QPainter:

                    Then at the end of paint event, save the painter to a picture (QPixmap). Then in next paint event, first paint the pixmap

                    now i'm trying to do this.
                    There is a QPainter::drawPixmap to draw the saved image, but i can't find how to save the QPainter content to a QPixmap first, can you please give me a hint ?

                    1 Reply Last reply
                    0
                    • ODБOïO Offline
                      ODБOïO Offline
                      ODБOï
                      wrote on last edited by ODБOï
                      #13

                      almost working, just need to fix the save and reload feature

                      
                      class MainWindow : public QMainWindow
                      {
                          Q_OBJECT
                      
                      public:
                          MainWindow(QWidget *parent = nullptr);
                          ~MainWindow();
                      protected:
                          void paintEvent(QPaintEvent *event)
                          {
                      
                              Q_UNUSED(event)
                              if(!painter->isActive()){
                                  painter->begin(this);
                              }
                      
                              drawLineW(qrand()%250, qrand()%250,(qrand()%10 > 5)?true:false);
                          }
                      
                          void drawLineW(int x, int y, bool down){
                      
                              // load last path/picture
                              painter->drawPixmap(0,0,this->height(),this->width(),oldPath);
                      
                              if(down){
                                  painter->setPen(QPen(Qt::blue, 3, Qt::DashDotLine, Qt::RoundCap));
                              }else{
                                  painter->setPen(QPen(Qt::red, 3, Qt::DashDotLine, Qt::RoundCap));
                              }
                      
                              painter->drawLine(lastX,lastY,x,y);
                              painter->end();
                      
                              lastX = x;
                              lastY = y;
                      
                              // save current path/picture
                              oldPath = QPixmap::fromImage(oldPathImg);
                      
                          }
                      
                      private:
                          int lastX=0;
                          int lastY=0;
                      
                          QImage oldPathImg;
                      
                          QPixmap oldPath;
                      
                          QPainter* painter;
                          QTimer * drawTimer;
                          Ui::MainWindow *ui;
                      };
                      #endif // MAINWINDOW_H
                      
                      
                      // ___
                      
                      MainWindow::MainWindow(QWidget *parent)
                          : QMainWindow(parent)
                          , ui(new Ui::MainWindow)
                      {
                          ui->setupUi(this);
                      
                          drawTimer = new QTimer(this);
                      
                          painter = new QPainter(&oldPathImg);
                      
                          drawTimer->setInterval(1000);
                      
                          QObject::connect(drawTimer,&QTimer::timeout,[=](){
                              update();
                          });
                      
                          drawTimer->start();
                      }
                      
                      
                      
                      1 Reply Last reply
                      0
                      • ODБOïO Offline
                        ODБOïO Offline
                        ODБOï
                        wrote on last edited by ODБOï
                        #14

                        This was 1000 times easier using Graphics View...

                        class MainWindow : public QMainWindow
                        {
                            Q_OBJECT
                        
                        public:
                            MainWindow(QWidget *parent = nullptr);
                            ~MainWindow();
                        private:
                            int oldX=0;
                            int oldY=0;
                            Ui::MainWindow *ui;
                            QGraphicsScene *scene;
                            QTimer *drawTimer;
                            QGraphicsLineItem *vect;
                        
                            QVector <QPoint> path;
                        
                            int nLine = 0;
                        
                            void createPath(){
                                for(int i=1;i<20;i++){
                                      path.append(QPoint(i*10,(i%2)*10));
                                }
                            }
                        };
                        //___ cpp
                        MainWindow::MainWindow(QWidget *parent)
                            : QMainWindow(parent)
                            , ui(new Ui::MainWindow)
                        {
                            ui->setupUi(this);
                            scene = new QGraphicsScene(this);
                            ui->graphicsView->setScene(scene);
                        
                            drawTimer = new QTimer(this);
                            drawTimer->setInterval(50);
                        
                            createPath();
                        
                            QObject::connect(drawTimer,&QTimer::timeout,[=](){
                                if(nLine>=path.length()){
                        
                                    drawTimer->stop();
                                    return;
                                }
                        
                                int newX = path.at(nLine).x();
                                int newY = path.at(nLine).y();
                        
                                vect = scene->addLine(oldX,oldY,newX,newY);
                        
                                oldX= newX;
                                oldY= newY;
                        
                                nLine++;
                        
                            });
                            drawTimer->start();
                        }
                        
                        1 Reply Last reply
                        2

                        • Login

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