Как нарисовать прямоугольник на пользовательском видео виджете т в QT? - PullRequest
0 голосов
/ 27 октября 2018

Я хочу выделить область в пользовательском виджете видео и нарисовать прямоугольник в выбранной области.

Пока что я могу выбрать область с 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 голосов
/ 27 октября 2018

Когда вы создаете указатель: QPainter *painter, это может указывать на любую память, так как она содержит мусор.поэтому, когда вы делаете painter->begin(this), вы получаете доступ к неинициализированной памяти, поэтому вы получаете эту ошибку.С другой стороны, QWidget, например QVideoWidget, следует рисовать только в методе paintEvent, стратегия состоит в том, чтобы иметь переменные, сохраняющие состояние того, что вы хотите рисовать, например, QRect, ивызовите обновление, чтобы нарисовать его.

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