c++ - 如何在 QT 中的自定义视频小部件 t 上绘制矩形?
问题描述
我想在自定义视频小部件上选择一个区域并在所选区域上绘制矩形。
到目前为止,我可以使用 QRubberband 选择一个区域,但是在释放左键后我无法绘制矩形。
每当我单击拖动然后释放以绘制矩形时,它都会出现此错误:
QBackingStore::endPaint() 在 backingstore 绘制设备上使用活动绘制器调用
程序意外结束。
这是我的代码:
我的视频对象.h
#ifndef MYVIDEOOBJECT_H
#define MYVIDEOOBJECT_H
#include <QObject>
#include <QVideoWidget>
#include <QRubberBand>
#include <QPainter>
#include <QPen>
#include <QPaintEvent>
#include <QRect>
#include <QMouseEvent>
#include <QDebug>
class MyVideoObject : public QVideoWidget
{
Q_OBJECT
public:
explicit MyVideoObject(QWidget *parent = 0);
void mouseMoveEvent(QMouseEvent *ev);
void mousePressEvent(QMouseEvent *ev);
void mouseReleaseEvent(QMouseEvent *ev);
void paintEvent(QPaintEvent *ev);
private:
QRubberBand* rubberBand;
QPainter* painter;
//QRect *rectangle;
QPoint origin;
QPoint endPoint;
};
#endif // MYVIDEOOBJECT_H
我的视频对象.cpp
#include "myvideoobject.h"
MyVideoObject::MyVideoObject(QWidget* parent) :
QVideoWidget(parent)
{
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
rubberBand->setGeometry(0,0,50,50);//ileride silebilrisin
}
void MyVideoObject::mouseMoveEvent(QMouseEvent *ev)
{
rubberBand->setGeometry(QRect(origin,ev->pos()).normalized());
}
void MyVideoObject::mousePressEvent(QMouseEvent *ev)
{
origin = ev->pos();
if(!rubberBand)
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
rubberBand->setGeometry(QRect(origin,QSize()));
rubberBand->show();
}
void MyVideoObject::mouseReleaseEvent(QMouseEvent *ev)
{
rubberBand->hide();
endPoint = ev->pos();
painter->begin(this);
painter->drawRect(QRect(origin,endPoint));
}
void MyVideoObject::paintEvent(QPaintEvent *ev)
{
QRect rect = ev->rect();
painter = new QPainter(this);
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(Qt::black);
painter->drawText(rect,Qt::AlignCenter,"Data");
painter->drawRect(rect);
//painter->setPen(Qt::red);
}
我没有添加 mainwindow.cpp 和 mainwindow.h 因为除了使用 openfiledialog 选择视频之外没有太多代码。
解决方案
当你创建一个指针:QPainter *painter
时,它可以指向任何内存,因为它有垃圾。因此,当您painter->begin(this)
访问未初始化的内存时,这就是您收到该错误的原因。另一方面,在QWidget
只QVideoWidget
应该在方法中绘制的情况下paintEvent
,策略是拥有保存您想要绘制的状态的变量,例如QRect
,并调用更新来绘制它。
我的视频对象.h
#ifndef MYVIDEOOBJECT_H
#define MYVIDEOOBJECT_H
#include <QVideoWidget>
class QRubberBand;
class MyVideoObject : public QVideoWidget
{
public:
MyVideoObject(QWidget *parent = nullptr);
protected:
void mouseMoveEvent(QMouseEvent *ev);
void mousePressEvent(QMouseEvent *ev);
void mouseReleaseEvent(QMouseEvent *ev);
void paintEvent(QPaintEvent *ev);
private:
QRubberBand *rubberBand;
QPoint origin;
QRect rect;
};
#endif // MYVIDEOOBJECT_H
我的视频对象.cpp
#include "myvideoobject.h"
#include <QMouseEvent>
#include <QPainter>
#include <QRubberBand>
MyVideoObject::MyVideoObject(QWidget *parent):
QVideoWidget(parent),
rubberBand(nullptr){}
void MyVideoObject::mousePressEvent(QMouseEvent *ev)
{
origin = ev->pos();
if(!rubberBand)
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
rubberBand->setGeometry(QRect(origin,QSize()));
rubberBand->show();
QVideoWidget::mousePressEvent(ev);
}
void MyVideoObject::mouseMoveEvent(QMouseEvent *ev)
{
rubberBand->setGeometry(QRect(origin,ev->pos()).normalized());
QVideoWidget::mouseMoveEvent(ev);
}
void MyVideoObject::mouseReleaseEvent(QMouseEvent *ev)
{
rect = rubberBand->geometry();
update();
QVideoWidget::mouseReleaseEvent(ev);
}
void MyVideoObject::paintEvent(QPaintEvent *ev)
{
QVideoWidget::paintEvent(ev);
QPainter painter(this);
painter.save();
painter.setBrush(Qt::red);
if(!rect.isNull())
painter.drawRect(rect);
painter.restore();
}
推荐阅读
- java - 返回 Vavr 的链接函数
- c - 错误:8.13802e+06 超出“无符号字符”类型的可表示值范围
- javascript - 正则表达式字符串开始/结束/中间一次匹配
- javascript - 等待函数内的多个ajax调用?
- java - 如何使用 BFS 计算到 Graph 中所有其他顶点的距离?
- python - 根据其他字段的计算,在 pandas 数据框中一次创建两个新字段
- c# - C#中的连续关键字
- sql-server - 如何将记录从一个表复制到另一个 SQL Server
- java - 使用自定义消息完成 for 循环后抛出异常
- jestjs - 当 Jest 测试用例失败或抛出错误时,Gitlab 管道不会失败