问题
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.
回答1:
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();
}
回答2:
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.
来源:https://stackoverflow.com/questions/25454833/how-to-draw-on-the-top-of-an-inherited-widget-vlcvideowidget