How to draw on the top of an inherited widget (Vlc

2019-06-01 17:06发布

How can I draw something on a VLC Video Widget?

I'm using VLC-Qt library to play video on a widget in my Qt application. My application requires drawing a text (or something like) on all videos. I already tried subclassing VlcWidgetVideo and reimplementing paintEvent. The method works when no video is playing. Though immadiately after starting to play, my paintings disappear. It looks like they are under VLC's video...

The code:

class TrackerWidgetVideo : public VlcWidgetVideo{
// Blah blah blah
protected:
    void paintEvent(QPaintEvent *);
}
// .......
void TrackerWidgetVideo::paintEvent(QPaintEvent *e)
{
    VlcWidgetVideo::paintEvent(e);
    QPainter p(this);
    p.drawText(rect(), Qt::AlignCenter, "Some foo goes here"); // This paints
}

Following images describe the situation better. First screenshot is when no video is playing. Second one is when I open a video file.

When not playing video

Playing a video

2条回答
爷的心禁止访问
2楼-- · 2019-06-01 17:20

It looks like you want to create an overlay. If you take a look at WidgetVideo.cpp in the source for vlc-qt, you can see that the request() method creates a widget and adds it to a layout which is parented to the VlcVideoWidget. This is probably messing with the overlay you're painting in your paintEvent.

To create an overlay that should stay on top of your video, follow the method outlined here: http://developer.nokia.com/community/wiki/How_to_overlay_QWidget_on_top_of_another

You should add an instance of the overlay class to your instance of TrackerWidgetVideo. The overlay class will contain the overriden paintEvent method that is currently part of your TrackerWidgetVideo. Then, you'll override TrackerWidgetVideo::resizeEvent to resize your overlay class instance.

Here's some example code:

Overlay.h

class Overlay : public QWidget
{
    Q_OBJECT

 public:
    Overlay(QWidget* parent);

 protected:
    void paintEvent(QPaintEvent* event);
};

Overlay.cpp

Overlay::Overlay(QWidget* parent) : QWidget(parent)
{
    setPalette(Qt::transparent);
    setAttribute(Qt::WA_TransparentForMouseEvents);
}

void Overlay::paintEvent(QPaintEvent* event)
{
    QPainter p(this);
    p.drawText(rect(), Qt::AlignCenter, "Some foo goes here");
}

TrackerWidgetVideo.h

class TrackerWidgetVideo : public VlcWidgetVideo
{
    Q_OBJECT

 public:
    explicit VlcWidgetVideo(QWidget* parent = NULL);

 protected:
    void resizeEvent(QResizeEvent* event);

 private:
    Overlay* overlay;
};

TrackerWidgetVideo.cpp

TrackerWidgetVideo::TrackerWidgetVideo(QWidget* parent) : VlcWidgetVideo(parent)
{
    overlay = new Overlay(this);
}

void TrackerWidgetVideo::resizeEvent(QResizeEvent* event)
{
    overlay->resize(event->size());
    event->accept();
}
查看更多
你好瞎i
3楼-- · 2019-06-01 17:32

Vlc creates two "internal" widgets on VlcVideoWidget when video is playing. Create a new widget as the VlcVideoWidget's sibling(not child), bring it to front and paint on it.

查看更多
登录 后发表回答