記事ディレクトリ
序文
この記事では主に、QPainter を使用して QLabel に画像を表示する方法と、イベント フィルターを使用して QLabel が QEvent::Paint イベントをキャプチャできるようにする方法、およびマウス イベントを組み合わせて画像上に他のグラフィックスを描画する方法について説明します。サンプルコードについては記事の内容を参照してください。学習の参考にしてください。間違いがあれば批判して修正してください。
事業効果
提示:以下是本篇文章正文内容,下面案例可供参考
1. イベントフィルター
Qt のイベント フィルターはコントロールの描画イベントをフィルターするため、コントロールに描画することはできません。QLabel に画像を表示し、その上に他のグラフィックを描画するには、まずこのコントロールのイベント フィルターをインストールする必要があります。その後、書き換えます。 bool eventFilter(QObject *obj, QEvent *event) のコードは次のとおりです。イベント フィルターのより詳細な理解については、このブログを参照してください: Qt イベント フィルター (2 番目の理解)
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. 完全なコードの表示例
1.ウィジェット.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.ウィジェット.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.ウィジェット.ui
3. ダウンロードリンク
私の Baidu ネットワーク ディスク リンクの例: https://pan.baidu.com/s/1wJj8UHgr7Aub-7p8pojnrw
抽出コード: xxcj
要約する
この記事の例では、Qt のイベント フィルターを使用し、QPaintEvent や QMouseEvent などのイベントを書き換えます。これも比較的一般的な方法です。今後の仕事では、自分たちのニーズに合わせてイベント システムを柔軟に使用する方法を学ばなければなりません。この例で注意すべき点は、ここで QLabel に画像を表示するには、QLabel の setPixmap メソッドの代わりに QPainter のdrawPixmap を使用する必要があることです。そうしないと、線を描画するときに状況が表示されません (実際には描画されますが、アップの写真によってブロックされています)。
こんにちは:
一緒に学び、一緒に進歩しましょう。関連する質問がまだある場合は、ディスカッションのためにコメント領域にメッセージを残すことができます。