如何在QT中的自定义视频窗口小部件t上绘制矩形?

时间:2018-10-27 16:38:28

标签: c++ qt widget paintevent

我想在自定义视频窗口小部件上选择一个区域,然后在所选区域上绘制矩形。

到目前为止,我可以选择具有QRubberband的区域,但是在释放左键单击后无法绘制矩形。

每当我单击并拖动以绘制矩形时,都会出现此错误:

  

QBackingStore :: endPaint()在后备存储绘制设备上用活动绘制程序调用

     

程序意外完成。

这是我的代码:

myvideoobject.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

myvideoobject.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选择视频外,这些代码中没有太多代码。

1 个答案:

答案 0 :(得分:1)

创建指针QPainter *painter时,由于它有垃圾,因此可以指向任何内存。因此,当您执行painter->begin(this)时,您正在访问未初始化的内存,这就是为什么会出现该错误的原因。另一方面,在QWidget之类的QVideoWidget中仅应在方法paintEvent中进行绘制,例如,策略是使用变量来保存要绘制的内容的状态。 QRect,然后调用update对其进行绘制。

myvideoobject.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

myvideoobject.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();
}