首页 > 解决方案 > 如何在 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 选择视频之外没有太多代码。

标签: c++qtwidgetpaintevent

解决方案


当你创建一个指针:QPainter *painter时,它可以指向任何内存,因为它有垃圾。因此,当您painter->begin(this)访问未初始化的内存时,这就是您收到该错误的原因。另一方面,在QWidgetQVideoWidget应该在方法中绘制的情况下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();
}

推荐阅读