Draw basic Axes on QPixmap ?


  • Moderators

    @r-p-h than I would suggest to do what I said, previously



  • @j-hilk said in Draw basic Axes on QPixmap ?:

    @r-p-h than I would suggest to do what I said, previously

    Ok, but how do I go about inserting a QChartView where I want it in the GUI because as you said it isn't available as a widget in QTDesigner and my GUI is in "grid" layout...


  • Moderators

    @r-p-h
    you're mixing myself and @Pl45m4 ;)

    I said subclassing QLabel

    #include <QApplication>
    #include <QLabel>
    #include <QPainter>
    #include <QDebug>
    
    class myLabel : public QLabel
    {
    public:
        explicit myLabel(QWidget *parent = nullptr) : QLabel(parent) {
            QImage img(200,200, QImage::Format_RGB888);
            img.fill(Qt::green);
            m_pixmap = QPixmap::fromImage(img);
        }
    
    private:
        QPixmap m_pixmap;
    protected:
        virtual void paintEvent(QPaintEvent *event)override{
            QLabel::paintEvent(event);//Basic drawing of the Parent class -> styles etc
            QPainter p(this);
    
            p.drawPixmap(0,0,width(), height(),m_pixmap);
            p.setPen(QPen(Qt::red));
            p.drawLine(QPointF(10,0), QPointF(10, height()));
            p.drawLine(QPointF(0, height() - 10), QPointF(width(), height() -10));
        }
    };
    
    
    int main(int argc, char *argv[])
    {
    
        QApplication a(argc, argv);
    
        myLabel m;
        m.resize(400,400);
        m.show();
    
        return  a.exec();
    }
    


  • @j-hilk said in Draw basic Axes on QPixmap ?:

    @r-p-h
    you're mixing myself and @Pl45m4 ;)

    I said subclassing QLabel

    #include <QApplication>
    #include <QLabel>
    #include <QPainter>
    #include <QDebug>
    
    class myLabel : public QLabel
    {
    public:
        explicit myLabel(QWidget *parent = nullptr) : QLabel(parent) {
            QImage img(200,200, QImage::Format_RGB888);
            img.fill(Qt::green);
            m_pixmap = QPixmap::fromImage(img);
        }
    
    private:
        QPixmap m_pixmap;
    protected:
        virtual void paintEvent(QPaintEvent *event)override{
            QLabel::paintEvent(event);//Basic drawing of the Parent class -> styles etc
            QPainter p(this);
    
            p.drawPixmap(0,0,width(), height(),m_pixmap);
            p.setPen(QPen(Qt::red));
            p.drawLine(QPointF(10,0), QPointF(10, height()));
            p.drawLine(QPointF(0, height() - 10), QPointF(width(), height() -10));
        }
    };
    
    
    int main(int argc, char *argv[])
    {
    
        QApplication a(argc, argv);
    
        myLabel m;
        m.resize(400,400);
        m.show();
    
        return  a.exec();
    }
    

    Sorry you're correct, I was confusing the two of you. Why does this need to be in a class format like how you showed ? Can I not directly paint the QLabel ? Also I usually resize the image to the size of the label before putting it in QLabel. Now will this still be possible - won't the pixmap get cut off or over extend past the label when drawing it...


  • Lifetime Qt Champion

    Hi
    yes you can do it without wrapping in a class, even i must say its a bit nicer. ( the way @J.Hilk has shown)

    int GetBarHeight(int MAX) {
      return rand() % (MAX - 5) + 5;
    }
    
    void MainWindow::on_pushButton_released() {
    
      int h = ui->label->height();
      int w = ui->label->width();
    
      QPixmap pix(w, h);
      QPainter paint(&pix);
      pix.fill( Qt::white );
      paint.setPen(QColor(0, 0, 0, 255));
    
    
      int y = 0;
      int x = 0;
    
      int bw = 10; // bar width
      for (int barcount = 0; barcount < 12; ++barcount) {
        paint.setBrush(QColor(255 - x, 34 + x, 255, 255));
        paint.drawRect(x, h - GetBarHeight(h),  bw, h );
        x += bw + 4;
      }
      paint.end();
      ui->label->setPixmap(pix);
    }
    
    

    alt text

    test project
    https://www.dropbox.com/s/qwde8lb0fkjrrh3/mycheapgraph.zip?dl=0


  • Moderators

    @r-p-h

    Sorry you're correct, I was confusing the two of you.

    No worries 😉

    Why does this need to be in a class format like how you showed ? Can I not directly paint the QLabel ?

    no, painting on a QLabel can only be done inside the paintEvent function. To access that function subclassing is requiert

    Also I usually resize the image to the size of the label before putting it in QLabel. Now will this still be possible - won't the pixmap get cut off or over extend past the label when drawing it...

    in the example the pixmap actually get’s stretched. In the end you have full control over it. But IIRC you will never be able to paint outside a Qwidgets boundaries.

    ———
    That said, you can potentially use the QPainter on the QPixmap directly and draw the axis that way.

    Edit: @mrjj beat me to it, with an actual example as well 😳



  • Thanks @J-Hilk and @mrjj , I will give it a try and see how it goes. ;)


  • Lifetime Qt Champion

    Hi
    Regarding the axis.
    One option is to simply draw them in inkscape and save as SVG.
    Then just paint the SVG on top of the image.
    That should be faster than draw the ticks and values by hand using painter.
    However, if axis values change or zoom is needed then its not good idea.



  • @mrjj said in Draw basic Axes on QPixmap ?:

    Hi
    Regarding the axis.
    One option is to simply draw them in inkscape and save as SVG.
    Then just paint the SVG on top of the image.
    That should be faster than draw the ticks and values by hand using painter.
    However, if axis values change or zoom is needed then its not good idea.

    Hi, the "plot/image" is not interactive. The axis values do change but only each time a user changes a setting. So the axis would have to somehow be made on the fly for each "session". During the "session" the axis remain the same though while the image does change ! So I'm not sure what's the most efficient way of doing it...


  • Lifetime Qt Champion

    @r-p-h
    Well if its very dynamic then hand painting them with painter should do it.
    Overlaying a svg with only part of the axis is likely more fiddle fiddle to place the values correctly
    so just drawing it should be the way to go.
    Do you have image of the needed axis?



  • @mrjj said in Draw basic Axes on QPixmap ?:

    @r-p-h
    Well if its very dynamic then hand painting them with painter should do it.
    Overlaying a svg with only part of the axis is likely more fiddle fiddle to place the values correctly
    so just drawing it should be the way to go.
    Do you have image of the needed axis?

    The image is live though so it's constantly being displayed in a loop, so I'm not sure if re-drawing the axes constantly is such a good idea.


  • Lifetime Qt Champion

    @r-p-h
    oh, well for that sort of overlay,
    you will need to draw the axis
    anytime the image changes regardlessly.



  • @mrjj said in Draw basic Axes on QPixmap ?:

    @r-p-h
    oh, well for that sort of overlay,
    you will need to draw the axis
    anytime the image changes regardlessly.

    Hi, Surely I could just draw (or plot ?) the axes once in the beginning and then just display or draw the image inside the plot. I think that re-drawing the axes every time will be very inefficient. Also manually drawing the tick marks and values seems like it could become tedious, so maybe using some form of QChart is the way to go...


  • Lifetime Qt Champion

    Hi
    Well it sounds to me like the image is live ?
    Like a camera feed ?



  • @mrjj said in Draw basic Axes on QPixmap ?:

    Hi
    Well it sounds to me like the image is live ?
    Like a camera feed ?

    Yes. Pretty much.



  • @r-p-h
    QLabel *Label_backImg = new QLabel(this);
    Label_backImg->setMinimumSize(80,80);
    Label_backImg->setMaximumSize(80,80);
    Label_backImg->setPixmap(QPixmap(":/images/edit-icon.png").scaled (Label_backImg->width(),Label_backImg->height(),Qt::KeepAspectRatio));

    QLabel *labelIcon = new QLabel(Label_backImg);
    labelIcon->setGeometry(40,8,40,40);
    labelIcon->setPixmap(QPixmap(":/images/notification.png").scaled (labelIcon->width(),labelIcon->height(),Qt::KeepAspectRatio));
    

    result image is :
    0_1566199247348_Screenshot_2019-08-19_12-49-21.png



  • @anil_arise said in Draw basic Axes on QPixmap ?:

    @r-p-h
    QLabel *Label_backImg = new QLabel(this);
    Label_backImg->setMinimumSize(80,80);
    Label_backImg->setMaximumSize(80,80);
    Label_backImg->setPixmap(QPixmap(":/images/edit-icon.png").scaled (Label_backImg->width(),Label_backImg->height(),Qt::KeepAspectRatio));

    QLabel *labelIcon = new QLabel(Label_backImg);
    labelIcon->setGeometry(40,8,40,40);
    labelIcon->setPixmap(QPixmap(":/images/notification.png").scaled (labelIcon->width(),labelIcon->height(),Qt::KeepAspectRatio));
    

    result image is :
    0_1566199247348_Screenshot_2019-08-19_12-49-21.png

    Hi, with this approach I will have to first create the axis externally and save them as some sort of a transparent image ?



  • @r-p-h use only .png images


  • Banned

    This post is deleted!


  • @pl45m4 said in Draw basic Axes on QPixmap ?:

    A ChartView, but as you already said, you have to create it on runtime, because it`s not a Widget in Qt Designer.

    @jhoney
    I think @R-P-H doen't need the exact same answer again :)



  • Thanks for the support guys. I tried making a transparent QPixmap image using Qt::transparent fill for the axis and overlaying it onto my other QPixmap, however it didn't work properly. So I ended up just drawing directly onto the image itself. Not the most efficient method but it seems to work...