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. QT beginner using QPainter with a custom widget
Forum Updated to NodeBB v4.3 + New Features

QT beginner using QPainter with a custom widget

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 4 Posters 2.1k 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.
  • J Offline
    J Offline
    jkwok678
    wrote on last edited by jkwok678
    #1

    Hi,

    I'm currently using a custom Widget and trying to draw an image on to the canvas, but I can't currently do so, I've tried re-implementing the mouseEvent method, but currently nothing works. The +16 is for the size of the picture I'm testing with.

    Thanks

    #include "canvas.h"
    
    Canvas::Canvas()
    {
        setMinimumSize(1280,800);
        QPalette pal = palette();
    
        // set black background
        pal.setColor(QPalette::Background, Qt::white);
        setAutoFillBackground(true);
        setPalette(pal);
    }
    
    void Canvas::mouseClickEvent(QMouseEvent *event)
    {
    
        if (event->button() == Qt::LeftButton) {
             lastPoint = event->pos();
             drawELement(event->pos());
    
            }
    }
    
    void Canvas::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        QImage *image = new QImage(":/graphics/graphics/straightH.png");
    
        //painter.drawImage(Qpo,*image);
    }
    
    void Canvas::drawELement(QPoint place)
    {
        QPainter painter(this);
        QImage *image = new QImage(":/graphics/graphics/straightH.png");
        painter.drawImage(place.x(),place.y(),*image);
        modified = true;
    
        update(place.x(),place.y(),place.x()+16,place.y()+16);
    
    }
    
    
    jsulmJ 1 Reply Last reply
    0
    • J jkwok678

      @SGaist
      So, like this?
      Also does QPainter store what's been drawn on the screen or is it like JavaFX canvas, where it is more of a draw it then forget about it, as in the canvas doesn't know store what's drawn on the screen after. My reason for this question, is that I realised sometimes when I click adjacent to the existing images, sometimes those disappear, when that happens, does that still take memory?

      #include "canvas.h"
      
      Canvas::Canvas()
      {
          setMinimumSize(1280,800);
          QPalette pal = palette();
          imageSize=16;
          // set black background
          pal.setColor(QPalette::Background, Qt::white);
      
          setAutoFillBackground(true);
          setPalette(pal);
      }
      
      void Canvas::mousePressEvent(QMouseEvent *event)
      {
      
          if (event->button() == Qt::LeftButton) {
               lastPoint = event->pos();
               exactX = event->pos().x();
               exactY = event->pos().y();
               extraX = exactX%16;
               extraY = exactY%16;
               finalX = exactX - extraX;
               finalY = exactY - extraY;
               boundX = finalX+imageSize;
               boundY = finalY+imageSize;
               update(finalX,finalY,boundX,boundY);
      
      
              }
      }
      
      void Canvas::paintEvent(QPaintEvent *event)
      {
          QPainter painter(this);
          painter.drawImage(finalX,finalY,QImage(":/graphics/graphics/straightH.png"));
      
      }
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by jsulm
      #12

      @jkwok678 said in QT beginner using QPainter with a custom widget:

      Also does QPainter store what's been drawn on the screen

      It is explained in the documentation: https://doc.qt.io/qt-5/qwidget.html#paintEvent
      "When the paint event occurs, the update region has normally been erased, so you are painting on the widget's background."

      You should optimise this:

      painter.drawImage(finalX,finalY,QImage(":/graphics/graphics/straightH.png"));
      

      Creating new QImage from file on every paintEvent is expensive. Do it once and store QImage instance as class member.

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

      1 Reply Last reply
      2
      • J jkwok678

        Hi,

        I'm currently using a custom Widget and trying to draw an image on to the canvas, but I can't currently do so, I've tried re-implementing the mouseEvent method, but currently nothing works. The +16 is for the size of the picture I'm testing with.

        Thanks

        #include "canvas.h"
        
        Canvas::Canvas()
        {
            setMinimumSize(1280,800);
            QPalette pal = palette();
        
            // set black background
            pal.setColor(QPalette::Background, Qt::white);
            setAutoFillBackground(true);
            setPalette(pal);
        }
        
        void Canvas::mouseClickEvent(QMouseEvent *event)
        {
        
            if (event->button() == Qt::LeftButton) {
                 lastPoint = event->pos();
                 drawELement(event->pos());
        
                }
        }
        
        void Canvas::paintEvent(QPaintEvent *event)
        {
            QPainter painter(this);
            QImage *image = new QImage(":/graphics/graphics/straightH.png");
        
            //painter.drawImage(Qpo,*image);
        }
        
        void Canvas::drawELement(QPoint place)
        {
            QPainter painter(this);
            QImage *image = new QImage(":/graphics/graphics/straightH.png");
            painter.drawImage(place.x(),place.y(),*image);
            modified = true;
        
            update(place.x(),place.y(),place.x()+16,place.y()+16);
        
        }
        
        
        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by jsulm
        #2

        @jkwok678 Drawing is done inside paintEvent. So, in drawElements you only generate the image and store it as member variable in your class. Then move

        painter.drawImage(place.x(),place.y(),*image);
        

        to your paintEvent. You can store place as member variable as well.

        void Canvas::paintEvent(QPaintEvent *event)
        {
            QPainter painter(this);
            painter.drawImage(place, image);
        }
        
        

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

        1 Reply Last reply
        2
        • J Offline
          J Offline
          jkwok678
          wrote on last edited by
          #3

          Am i able to call the paintEvent method in the mouseClickEvent?

          The functionality I want is for me to me able to add a new picture to the screen every time, a click is registered?

          jsulmJ 1 Reply Last reply
          0
          • J jkwok678

            Am i able to call the paintEvent method in the mouseClickEvent?

            The functionality I want is for me to me able to add a new picture to the screen every time, a click is registered?

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

            @jkwok678 said in QT beginner using QPainter with a custom widget:

            Am i able to call the paintEvent method in the mouseClickEvent?

            There is no need for that (and you should not do so). Call update() instead it will trigger repaint.

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

            1 Reply Last reply
            1
            • J Offline
              J Offline
              jkwok678
              wrote on last edited by jkwok678
              #5

              I've gotten rid of that stuff, but now, it only draws when the Canvas is created, in the top left corner. Is this a case where I need signal and slot?As I want to draw an image everytime I click on a spot.

              #include "canvas.h"
              
              Canvas::Canvas()
              {
                  setMinimumSize(1280,800);
                  QPalette pal = palette();
              
                  // set black background
                  pal.setColor(QPalette::Background, Qt::white);
                  setAutoFillBackground(true);
                  setPalette(pal);
              }
              
              void Canvas::mouseClickEvent(QMouseEvent *event)
              {
              
                  if (event->button() == Qt::LeftButton) {
                       lastPoint = event->pos();
                       update();
              
              
              
                      }
              }
              
              void Canvas::paintEvent(QPaintEvent *event)
              {
                  QPainter painter(this);
                  QImage *image = new QImage(":/graphics/graphics/straightH.png");
                  painter.drawImage(lastPoint,*image);
                  //painter.drawImage(Qpo,*image);
              }
              
              
              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #6

                Hi,

                There's no mouseClickEvent. You likely want to use mousePressEvent.

                Note that you are currently leaking images a lot. Don't create them in the heap, there's no reason for that. And since you are using only one image, allocate it once in the constructor and re-use it in the paint event.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                A 1 Reply Last reply
                1
                • J Offline
                  J Offline
                  jkwok678
                  wrote on last edited by
                  #7
                  This post is deleted!
                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    jkwok678
                    wrote on last edited by
                    #8

                    So, I feel like I've made a few changes, but when clicking right next to an existing image, it currently deletes, one that is already there. I've used 16 for the size of the image right now. But I was wondering if it's maybe too precise. Because the image is 16x16 pixels and I've used update 16, so should it really be 15, instead?

                    #include "canvas.h"
                    
                    Canvas::Canvas()
                    {
                        setMinimumSize(1280,800);
                        QPalette pal = palette();
                        imageSize=16;
                        // set black background
                        pal.setColor(QPalette::Background, Qt::white);
                        straightHImage = new QImage(":/graphics/graphics/straightH.png");
                        setAutoFillBackground(true);
                        setPalette(pal);
                    }
                    
                    void Canvas::mousePressEvent(QMouseEvent *event)
                    {
                    
                        if (event->button() == Qt::LeftButton) {
                             lastPoint = event->pos();
                             exactX = event->pos().x();
                             exactY = event->pos().y();
                             extraX = exactX%16;
                             extraY = exactY%16;
                             finalX = exactX - extraX;
                             finalY = exactY - extraY;
                             boundX = finalX+imageSize;
                             boundY = finalY+imageSize;
                             update(finalX,finalY,boundX,boundY);
                    
                    
                            }
                    }
                    
                    void Canvas::paintEvent(QPaintEvent *event)
                    {
                        QPainter painter(this);
                        painter.drawImage(finalX,finalY,*straightHImage);
                    
                    }
                    
                    
                    
                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      As I already wrote: there's no need to allocate your QImage on the heap.

                      As for your issu, one simple way is to keep a list of points and repaint the image for each of them.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      J 1 Reply Last reply
                      3
                      • SGaistS SGaist

                        Hi,

                        There's no mouseClickEvent. You likely want to use mousePressEvent.

                        Note that you are currently leaking images a lot. Don't create them in the heap, there's no reason for that. And since you are using only one image, allocate it once in the constructor and re-use it in the paint event.

                        A Offline
                        A Offline
                        Asperamanca
                        wrote on last edited by
                        #10

                        @SGaist said in QT beginner using QPainter with a custom widget:

                        Hi,

                        There's no mouseClickEvent. You likely want to use mousePressEvent.

                        Use the "override" keyword in the header file when you want to re-implement a base class function. It will help you catch errors like this one.

                        1 Reply Last reply
                        4
                        • SGaistS SGaist

                          As I already wrote: there's no need to allocate your QImage on the heap.

                          As for your issu, one simple way is to keep a list of points and repaint the image for each of them.

                          J Offline
                          J Offline
                          jkwok678
                          wrote on last edited by
                          #11

                          @SGaist
                          So, like this?
                          Also does QPainter store what's been drawn on the screen or is it like JavaFX canvas, where it is more of a draw it then forget about it, as in the canvas doesn't know store what's drawn on the screen after. My reason for this question, is that I realised sometimes when I click adjacent to the existing images, sometimes those disappear, when that happens, does that still take memory?

                          #include "canvas.h"
                          
                          Canvas::Canvas()
                          {
                              setMinimumSize(1280,800);
                              QPalette pal = palette();
                              imageSize=16;
                              // set black background
                              pal.setColor(QPalette::Background, Qt::white);
                          
                              setAutoFillBackground(true);
                              setPalette(pal);
                          }
                          
                          void Canvas::mousePressEvent(QMouseEvent *event)
                          {
                          
                              if (event->button() == Qt::LeftButton) {
                                   lastPoint = event->pos();
                                   exactX = event->pos().x();
                                   exactY = event->pos().y();
                                   extraX = exactX%16;
                                   extraY = exactY%16;
                                   finalX = exactX - extraX;
                                   finalY = exactY - extraY;
                                   boundX = finalX+imageSize;
                                   boundY = finalY+imageSize;
                                   update(finalX,finalY,boundX,boundY);
                          
                          
                                  }
                          }
                          
                          void Canvas::paintEvent(QPaintEvent *event)
                          {
                              QPainter painter(this);
                              painter.drawImage(finalX,finalY,QImage(":/graphics/graphics/straightH.png"));
                          
                          }
                          
                          jsulmJ 1 Reply Last reply
                          0
                          • J jkwok678

                            @SGaist
                            So, like this?
                            Also does QPainter store what's been drawn on the screen or is it like JavaFX canvas, where it is more of a draw it then forget about it, as in the canvas doesn't know store what's drawn on the screen after. My reason for this question, is that I realised sometimes when I click adjacent to the existing images, sometimes those disappear, when that happens, does that still take memory?

                            #include "canvas.h"
                            
                            Canvas::Canvas()
                            {
                                setMinimumSize(1280,800);
                                QPalette pal = palette();
                                imageSize=16;
                                // set black background
                                pal.setColor(QPalette::Background, Qt::white);
                            
                                setAutoFillBackground(true);
                                setPalette(pal);
                            }
                            
                            void Canvas::mousePressEvent(QMouseEvent *event)
                            {
                            
                                if (event->button() == Qt::LeftButton) {
                                     lastPoint = event->pos();
                                     exactX = event->pos().x();
                                     exactY = event->pos().y();
                                     extraX = exactX%16;
                                     extraY = exactY%16;
                                     finalX = exactX - extraX;
                                     finalY = exactY - extraY;
                                     boundX = finalX+imageSize;
                                     boundY = finalY+imageSize;
                                     update(finalX,finalY,boundX,boundY);
                            
                            
                                    }
                            }
                            
                            void Canvas::paintEvent(QPaintEvent *event)
                            {
                                QPainter painter(this);
                                painter.drawImage(finalX,finalY,QImage(":/graphics/graphics/straightH.png"));
                            
                            }
                            
                            jsulmJ Offline
                            jsulmJ Offline
                            jsulm
                            Lifetime Qt Champion
                            wrote on last edited by jsulm
                            #12

                            @jkwok678 said in QT beginner using QPainter with a custom widget:

                            Also does QPainter store what's been drawn on the screen

                            It is explained in the documentation: https://doc.qt.io/qt-5/qwidget.html#paintEvent
                            "When the paint event occurs, the update region has normally been erased, so you are painting on the widget's background."

                            You should optimise this:

                            painter.drawImage(finalX,finalY,QImage(":/graphics/graphics/straightH.png"));
                            

                            Creating new QImage from file on every paintEvent is expensive. Do it once and store QImage instance as class member.

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

                            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