在Ubuntu的QT5中将透明QWidget放在QMediaView之上

时间:2013-06-03 02:32:11

标签: c++ ubuntu video user-interface qt5

目标

我希望基于QT5的GUI的背景是正在播放的视频文件。我还希望能够以透明的方式设置我的GUI组件的样式,以便通过它们显示视频。

我不确定这是否完全可以实现。可能是因为我错过了一条重要线索(我毕竟是Qt初学者),或者可能只是因为它本身并不适合工作。但作为乐观主义者,我已经尽力了。

首次尝试

我的第一次尝试看起来像这样:

int main( int argc, char **argv ){
    QApplication app(argc, argv);
    QMediaPlayer *media=new QMediaPlayer(0);
    QVideoWidget *video=new QVideoWidget(0); //new QGLWidget()
    media->setVideoOutput(video);
    media->setMedia(QUrl::fromLocalFile("/tmp/avatar.mp4"));
    media->setPosition(3000000);
    media->play();
    QPushButton *pb=new QPushButton(video);
    pb->setText(QString("BOB"));
    //pb->setStyleSheet(QString("background:transparent;"));
    video->show();
    return app.exec();
}

按钮位于播放视频的顶部,这很好。但如果仔细观察,您会在按钮的角落看到一些黑色像素,表示它在视频上不透明,但呈现为不透明的矩形。

First result screenshot

第二次尝试

我尝试使用background:transparent;设置按钮样式(请参阅上面代码中的注释行)。这使按钮的背景透明,但按钮后面的黑框现在更加明显。

enter image description here

其他尝试

我已经在网上阅读了几个关于如何做到这一点的技巧。没有人对我有用。我曾尝试使用QGraphicsScene和朋友,不同的布局堆栈,有问题的小部件上的不同属性等等。我的最后一次尝试是将QVideoWidget的父级设置为QGLWidget()的实例,希望强制硬件加速能解决我的问题(我的计算机具有带二进制驱动程序的硬件3d加速)。这只是让窗口完全无法显示,而我仍然可以听到背景中播放的视频的音轨,表明应用程序仍在运行。

请求

我真的希望有一些善良而聪明的QT5开发人员可以帮助我实现我的梦想,即在Ubuntu的QT5中播放视频的小部件。

谢谢!

3 个答案:

答案 0 :(得分:6)

我知道这是一个老问题,您通过将部分应用程序转换为QML / QtQuick 2.2来设法解决您的问题,但我最终通过谷歌搜索碰到了它,而其他有相同问题的人也可能会发现这一点。我找到了一个适用于我的解决方案,并已在Windows上使用QT 5.3进行了测试。

我所做的是使用QGraphicsView来显示视频。这是我的代码(playerScreen是QGraphicsView):

QGraphicsVideoItem *item = new QGraphicsVideoItem;
item->setSize(ui->playerScreen->size());
player.reset(new QMediaPlayer());
player->setVideoOutput(item);
QGraphicsScene *scene = new QGraphicsScene(0, 0, ui->playerScreen->size().width(), ui->playerScreen->size().height());
ui->playerScreen->setScene(scene);
ui->playerScreen->scene()->addItem(item);

我禁用了playerScreen上的滚动条,否则会出现水平和垂直滚动条。

我在playerScreen的顶部有一个QWidget,我用QPainter绘制。 QWidget位于图形视图的顶部。

然后,当我播放视频时,我拨打ui->playerScreen-show()。我只是在游戏中这样做,因为我在顶部有另一个屏幕(对于与我的项目相关的其他内容),我需要在使用/不使用视频时调用show / hide:)

如果您需要有关我的代码的更多信息,请与我们联系。

答案 1 :(得分:2)

免责声明:我没有尝试过这个解决方案。它适用于Qt 4.8,可以将透明小部件放在OpenGL渲染的任何内容上。我只是假设媒体播放正在使用硬件加速。

黑色像素是Qt的后备缓冲区,其中执行软件渲染。该视频绕过了这个后备缓冲区,并且当一个常规的'绘制了qt小部件,它绘制在仍然处于初始状态(黑色)的后备缓冲区之上。

您可以将按钮(或包含按钮的小部件)设置为单独的透明窗口。

setWindowFlags(Qt::FramelessWindowHint | Qt::SplashScreen);
setAttribute(Qt::WA_TranslucentBackground);

您需要手动定位,因此它会跟随您的窗口。 这意味着按钮需要在窗口上安装eventfilter,并监听任何移动或调整事件大小。然后它会相对于窗口重新计算自己的位置,并更新它的位置。

答案 2 :(得分:-4)

qwidget4.1

void setAutoFillBackground(bool enabled)//你有那个方法,试试吧。

之前总是在论坛中搜索,因为有很多答案。 :)不是我想的,它对你来说更快。

A qt widget with fully transparent background