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

    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