最近公司项目中有一个需求,要在视频播放窗口上自由绘制图形。经过研究可以通过在视频播放窗口上添加一个顶层透明的窗口,在透明窗口上直接绘图的方式实现。
1.绘图采用QGraphicsView控件,添加QGraphicsScene的方式,代码中只是简单的画线,可以扩展画矩形、圆形、文字等,另外这种方式还可以对绘制的图形做翻转、缩放等操作,方便简单
2.代码中包含图像清除功能,透明窗口的清除不能像白板似的改变线的颜色就能实现
3.支持mac和windows,这两种系统在设置透明的时候稍微有些差别,代码中有说明,可以试一下
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPen>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
private:
Ui::Widget *ui;
QGraphicsView *m_graphicsView;
QGraphicsScene *m_scene;
QPoint m_pStart;
QPen m_pen;
bool m_isPressed;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget),
m_isPressed(false)
{
ui->setupUi(this);
//设置无边界窗口并置顶
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setMouseTracking(true);
//窗口设置透明
setAttribute(Qt::WA_TranslucentBackground,true);
setFixedSize(500,500);
m_graphicsView = new QGraphicsView(this);
//设置鼠标穿透效果
m_graphicsView->setAttribute(Qt::WA_TransparentForMouseEvents);
m_graphicsView->setStyleSheet("background:transparent;");
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_graphicsView->setGeometry(0,0,width(),height());
m_graphicsView->show();
//设置绘图场景
m_scene = new QGraphicsScene();
m_graphicsView->setScene(m_scene);
m_graphicsView->setSceneRect(0,0,width(),height());
m_pen.setStyle(Qt::SolidLine);
m_pen.setColor(Qt::red);
m_pen.setWidth(3);
move(0,0);
}
Widget::~Widget()
{
delete ui;
delete m_graphicsView;
}
void Widget::mousePressEvent(QMouseEvent *event)
{
m_isPressed = true;
m_pStart = event->pos();
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
if(m_isPressed){
QPoint pt = event->pos();
// 清除绘制内容(橡皮擦功能)
// QTransform transform;
// QGraphicsItem *item = m_scene->itemAt(pt,transform);
// if(item){
// m_scene->removeItem(item);
// }
//绘制图像
m_scene->addLine(m_pStart.x(),m_pStart.y(),pt.x(),pt.y(),m_pen);
m_pStart = pt;
}
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
m_isPressed = false;
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
#ifdef WIN32
painter.fillRect(this->rect(), QColor(255, 255, 255, 1));
#else
//mac电脑上需要将透明度设置为15,小于15鼠标控制画不上,15是临界值,是根据测试得来的,没有具体研究
painter.fillRect(this->rect(), QColor(255, 255, 255, 15));
#endif
}