Qt implements displaying pictures on QLabel and drawing lines/rectangular frames/polygons


foreword

This article mainly describes the use of QPainter to display pictures on QLabel, and use event filters to let QLabel capture QEvent::Paint events, and combine mouse events to draw other graphics on pictures. See the content of the article for the sample code, you can refer to it for study, if there are any mistakes, you are welcome to criticize and correct.

Project effect
Please add a picture description


提示:以下是本篇文章正文内容,下面案例可供参考

1. Event filter

Qt's event filter will filter the drawing events of the control, so you can't draw on any control. In order to display pictures on QLabel and draw other graphics on it, you first need to install an event filter for this control. Then rewrite bool eventFilter(QObject *obj, QEvent *event), the code is as follows. For a more detailed understanding of event filters, please refer to this blog: Qt event filter (second understanding)

void Widget::initWidget()
{
    
    
	//...
	//安装事件过滤器
	ui->lb_image->installEventFilter(this);
}

//重写eventFilter
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    
    
    if(watched ==ui->lb_image && event->type() == QEvent::Paint)
    {
    
    
        upPaint();
    }
    return QWidget::eventFilter(watched,event);
}

2. Example complete code display

1.widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPoint>
#include <QPen>
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include <QDir>

QT_BEGIN_NAMESPACE
namespace Ui {
    
     class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    
    
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void initWidget();
    void upPaint();

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    bool eventFilter(QObject *watched, QEvent *event);

private slots:
    void on_pb_line_1_clicked();
    void on_pb_line_2_clicked();
    void on_pb_rect_clicked();
    void on_pb_show_clicked();
    void on_pb_clear_clicked();

private:
    Ui::Widget *ui;

    bool isPressed;

    //line1
    int lineNum;
    bool lineFlag1;
    QPoint linePoint[5];

    //line2
    bool lineFlag2;
    QPoint lineStartPoint;
    QPoint lineEndPoint;

    //rect
    bool rectFlag;
    int rect[4] = {
    
    0};

};
#endif // WIDGET_H

2.widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);
    this->initWidget();
}

Widget::~Widget()
{
    
    
    delete ui;
}

void Widget::initWidget()
{
    
    
    isPressed = false;

    lineNum = 0;
    lineFlag1 = false;
    for(int i=0;i<5;i++)
    {
    
    
        linePoint[i] = QPoint(0,0);
    }

    lineFlag2 = false;
    lineStartPoint = QPoint(0,0);
    lineEndPoint = QPoint(0,0);

    rectFlag = false;

    ui->lb_image->installEventFilter(this);
}

void Widget::upPaint()     //绘图
{
    
        
    QPainter painter(ui->lb_image);
    //显示图片
    QString imagePath = "E:/PhotoTest/drawTest.PNG";   //图片对应路径
    painter.drawPixmap(0,0,400,300,QPixmap(imagePath));

    //显示图片的另一种方法:setPixmap,这里不要使用
    //QImage Image;
    //Image.load(imagePath);
    //ui->lb_image->setPixmap(QPixmap::fromImage(Image));

    QPen pen;
    pen.setColor(Qt::red);
    painter.setPen(pen);
    painter.drawRect(1,1,100,50);
    painter.drawText(10,30,"测试文字");

    if(lineFlag1)   //line1
    {
    
    
        if(lineNum == 2)
        {
    
    
            painter.drawLine(linePoint[0],linePoint[1]);
        }
        else if(lineNum == 3)
        {
    
    
            painter.drawLine(linePoint[0],linePoint[1]);
            painter.drawLine(linePoint[1],linePoint[2]);
        }
        else if(lineNum == 4)
        {
    
    
            painter.drawLine(linePoint[0],linePoint[1]);
            painter.drawLine(linePoint[1],linePoint[2]);
            painter.drawLine(linePoint[2],linePoint[3]);
        }
        else if(lineNum == 5)
        {
    
    
            painter.drawLine(linePoint[0],linePoint[1]);
            painter.drawLine(linePoint[1],linePoint[2]);
            painter.drawLine(linePoint[2],linePoint[3]);
            painter.drawLine(linePoint[3],linePoint[4]);
        }
        else if(lineNum == 6)
        {
    
    
            painter.drawLine(linePoint[0],linePoint[1]);
            painter.drawLine(linePoint[1],linePoint[2]);
            painter.drawLine(linePoint[2],linePoint[3]);
            painter.drawLine(linePoint[3],linePoint[4]);
            painter.drawLine(linePoint[4],linePoint[0]);
        }
    }
    if(lineFlag2)   //line2
    {
    
    
        painter.drawLine(lineStartPoint,lineEndPoint);
    }
    if(rectFlag)   //line2
    {
    
    
        painter.drawRect(rect[0],rect[1],rect[2],rect[3]);
    }

    //p.drawLine(QLine(100,100,100,250));
    //painter.drawRect(100,100,200,150);
}

//鼠标按下
void Widget::mousePressEvent(QMouseEvent *event)
{
    
    
    if(event->button() == Qt::LeftButton)
    {
    
    
        isPressed = true;
        if(lineFlag2)
        {
    
    
            lineStartPoint = QPoint(event->pos().x()-30,event->pos().y()-30);
            lineEndPoint = QPoint(event->pos().x()-30,event->pos().y()-30);
        }
        else if(rectFlag)
        {
    
    
            rect[0] = event->pos().x()-30;
            rect[1] = event->pos().y()-30;
        }
    }
}

//鼠标移动
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    
    
    if(isPressed)
    {
    
    
        if(lineFlag2)
        {
    
    
            lineEndPoint = QPoint(event->pos().x()-30,event->pos().y()-30);
        }
        else if(rectFlag)
        {
    
    
            rect[2] = event->pos().x()-30 - rect[0];
            rect[3] = event->pos().y()-30 - rect[1];
        }
        this->update();
    }
}

//鼠标抬起
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    
    
    qDebug()<<"Release:"<<QPoint(event->pos().x()-30,event->pos().y()-30);
    if(event->button() == Qt::LeftButton)
    {
    
    
        if(lineFlag1)
        {
    
    
            //多个点(以5个点示例)
            if(lineNum == 0)
            {
    
    
                lineNum = 1;
                linePoint[0] = QPoint(event->pos().x()-30,event->pos().y()-30);
                this->update();
            }
            else if(lineNum == 1)
            {
    
    
                lineNum = 2;
                linePoint[1] = QPoint(event->pos().x()-30,event->pos().y()-30);
                this->update();
            }
            else if(lineNum == 2)
            {
    
    
                lineNum = 3;
                linePoint[2] = QPoint(event->pos().x()-30,event->pos().y()-30);
                this->update();
            }
            else if(lineNum == 3)
            {
    
    
                lineNum = 4;
                linePoint[3] = QPoint(event->pos().x()-30,event->pos().y()-30);
                this->update();
            }
            else if(lineNum == 4)
            {
    
    
                lineNum = 5;
                linePoint[4] = QPoint(event->pos().x()-30,event->pos().y()-30);
                this->update();
            }
            else if(lineNum == 5)
            {
    
    
                lineNum = 6;
                this->update();
            }
            else
            {
    
    
                lineNum = 0;
                this->update();
            }
        }
        else if(lineFlag2)
        {
    
    
            isPressed=false;
            lineEndPoint = QPoint(event->pos().x()-30,event->pos().y()-30);
            this->update();
        }
        else if(rectFlag)
        {
    
    
            isPressed=false;
            rect[2] = event->pos().x()-30 - rect[0];
            rect[3] = event->pos().y()-30 - rect[1];
            this->update();
        }
    }
    else if(event->button() == Qt::RightButton)
    {
    
    
        isPressed=false;
        lineNum = 0;
        lineFlag1 = false;
        lineFlag2 = false;
        rectFlag = false;
        this->update();
    }
}

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    
    
    if(watched ==ui->lb_image && event->type() == QEvent::Paint)
    {
    
    
        upPaint();
    }
    return QWidget::eventFilter(watched,event);
}

void Widget::on_pb_line_1_clicked()
{
    
    
    lineFlag1 = true;
    lineFlag2 = false;
    rectFlag = false;
    this->update();
}

void Widget::on_pb_line_2_clicked()
{
    
    
    lineFlag1 = false;
    lineFlag2 = true;
    rectFlag = false;
    this->update();
}

void Widget::on_pb_rect_clicked()
{
    
    
    lineFlag1 = false;
    lineFlag2 = false;
    rectFlag = true;
    this->update();
}

void Widget::on_pb_show_clicked()
{
    
    
    lineFlag1 = true;
    lineFlag2 = true;
    rectFlag = true;
    this->update();
}

void Widget::on_pb_clear_clicked()
{
    
    
    isPressed = false;

    lineNum = 0;
    lineFlag1 = false;
    for(int i=0;i<5;i++)
    {
    
    
        linePoint[i] = QPoint(0,0);
    }

    lineFlag2 = false;
    lineStartPoint = QPoint(0,0);
    lineEndPoint = QPoint(0,0);

    rectFlag = false;
    for(int i=0;i<4;i++)
    {
    
    
        rect[i] = 0;
    }

    this->update();
}

3.widget.uiPlease add a picture description

3. Download link

My example Baidu network disk link: https://pan.baidu.com/s/1wJj8UHgr7Aub-7p8pojnrw
Extraction code: xxcj


Summarize

The example in this article uses Qt's event filter and rewrites events such as QPaintEvent and QMouseEvent, which is also a relatively common way. In our future work, we must learn to use the event system flexibly to meet our own needs. One thing to note in the example is that you need to use the drawPixmap in QPainter to display the picture on the QLabel here, instead of using the setPixmap method of QLabel, otherwise it will not be displayed when drawing the line (in fact, it is drawn, but it is blocked by the picture) up).


hello:
Learn together and make progress together. If you still have related questions, you can leave a message in the comment area for discussion.

Reference blog:
Qt event filter (second understanding)
QT displays pictures in QLabel and uses mouse click to draw lines

Guess you like

Origin blog.csdn.net/XCJandLL/article/details/127458147