Qt实现电子白板,双图层,下面显示视频帧,上面显示批注内容,支持画笔,橡皮檫
原理:
视频帧使用QImage显示,批注内容绘制在QPixmap上,QPainter显示绘制QImage,再绘制QPixmap
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTimer> #include <QDebug> #include <QPainter> // 画家类 #include <QPaintEvent> #include <QMouseEvent> #include <QPoint> #include <QPolygon> enum class HuabiType{Line, Rubber}; QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); void mousePressEvent(QMouseEvent* e); // 按下 void mouseMoveEvent(QMouseEvent* e); // 移动 void mouseReleaseEvent(QMouseEvent* e); // 释放 void paintEvent(QPaintEvent *); private: Ui::Widget *ui; QImage m_img; QPixmap m_draw; HuabiType m_type = HuabiType::Line; QList<QPoint> point_list; }; #endif // WIDGET_H
#include "widget.h" #include "ui_widget.h" #include <QListView> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); connect(ui->pushButton, &QPushButton::clicked, [=](){m_type = HuabiType::Line;}); connect(ui->pushButton_2, &QPushButton::clicked, [=](){m_type = HuabiType::Rubber;}); m_img.load("E:1.jpg"); m_draw = QPixmap(800, 600); m_draw.fill(Qt::transparent); } Widget::~Widget() { delete ui; } void Widget::mousePressEvent(QMouseEvent *e) { point_list.append(e->pos()); } void Widget::mouseMoveEvent(QMouseEvent *e) { point_list.append(e->pos()); update(); } void Widget::mouseReleaseEvent(QMouseEvent *e) { point_list.append(e->pos()); update(); point_list.clear(); } void Widget::paintEvent(QPaintEvent *) { QPainter p(this); QPen pen(QColor("red")); // 设置笔的颜色 pen.setWidth(3); // 设置笔-粗细 // 绘制视频帧 if(!m_img.isNull()) { p.drawImage(ui->widget->geometry(), m_img); } // 绘制批注 p.drawPixmap(ui->widget->geometry(), m_draw); // ========== QPainter p1(&m_draw); p1.setPen(pen); if(m_type == HuabiType::Line) { QPolygon pol; for(int i=0;i<point_list.count()-1;i++) { p1.drawLine(point_list.at(i), point_list.at(i+1)); } } else { p1.setCompositionMode(QPainter::CompositionMode_Clear); // 使用透明绘制模式 for(QPoint point: point_list) { QRect r(point.x() - 10, point.y() - 10, 20, 20); p1.eraseRect(r); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具