无法在不中断堆叠顺序的情况下使 QQuickWidget 背景透明
Posted
技术标签:
【中文标题】无法在不中断堆叠顺序的情况下使 QQuickWidget 背景透明【英文标题】:Unable to make QQuickWidget background transparent without break stacking order 【发布时间】:2017-01-17 11:42:51 【问题描述】:我在使 QQuickWidget
背景透明时遇到问题。
我想在QWidget
下方放置一个QQuickWidget
。 QQuickWidget
使用源 qml 文件。当我使用 Qt 4.8 时,我使用了QDeclarativeView
。从 Qt 4 移植到 Qt 5,QDeclarativeView
不再使用。因此,我使用QQuickWidget
而不是QDeclarativeView
,如下:
QWidget *mainWidget = new QWidget();
mainWidget->setStyleSheet("background-image: url(:/background.png);");
QQuickWidget *quick = new QQuickWidget(mainWidget);
quick->setAttribute(Qt::WA_TranslucentBackground, true);
quick->setAttribute(Qt::WA_AlwaysStackOnTop, true);
quick->setClearColor(Qt::transparent);
quick->setSource(QUrl("qrc:/image.qml"));
QWidget *topWidget = new QWidget(mainWidget);
topWidget->setStyleSheet("background-image: url(:/semitransparent.png);");
如果我这样做:
setAttribute(Qt::WA_AlwaysStackOnTop, true);
然后背景变得透明,但会破坏同一窗口内QQuickWidget
下方的其他小部件的堆叠顺序。
我想让QQuickWidget
在QWidget
下方时透明。这可能吗?如果没有,您建议什么解决方法?
(1)这是mainWidget的背景图片:
(2) 这是 QQuickWidget 的背景。 qml 文件使用此图像:
(3) 这是topWidget的背景图:
(4) 我想要什么:
(5) 当我将WA_AlwaysStackOnTop
设置为 false 时得到的结果:
(6) 当我将WA_AlwaysStackOnTop
设置为 true 时得到的结果:
【问题讨论】:
为什么要关心 QQuickWidget 是否透明,因为它在底部?它只是部分可见,您想确保根本看不到部分可见的部分吗? 我编辑了您的问题,但请查看此部分:“在同一窗口内涉及 QQuickWidget 下的其他小部件。”原句没有动词(“fiil”),所以我根据上下文推断了意思。 当使用WA_AlwaysStackOnTop
时,提供一个显示问题的屏幕截图会有所帮助。提供指向 imgur 屏幕截图的链接,我会将其放入问题的正文中。
首先感谢@Sabuncu。 Images。我希望这张图片有助于解释我的问题
我添加了内联图像,但我看不到黑白 1 和 2 的任何区别,除了颜色变化很小?另外,您应该分别发布background.png
和semitransparent.png
。
【参考方案1】:
http://doc.qt.io/qt-5/qquickwidget.html 此处的官方 QT 文档说,堆叠顺序的破坏是可以预料的:
当绝对必要时,可以通过设置来克服这个限制 QQuickWidget 上的 Qt::WA_AlwaysStackOnTop 属性。 请注意, 但是,这会破坏堆叠顺序。例如它不会 可能在 QQuickWidget 之上有其他小部件,所以它 只应在半透明的情况下使用 需要 QQuickWidget 以及下方可见的其他小部件。
另见此官方博文:http://blog.qt.io/blog/2014/07/02/qt-weekly-16-qquickwidget/
这篇最近的博客文章介绍了 QT 5.1 中的一项新功能:http://www.ics.com/blog/combining-qt-widgets-and-qml-qwidgetcreatewindowcontainer
结论:您看到的不是错误,而是 QT 框架的已知、公认、宣传的限制。
我的建议:不要试图通过 hack 来解决这个问题,而是重新设计你的 UI 方法。例如,也许你可以让topWidget
alpha-blend(半透明)。
编辑:例如,像这样:
【讨论】:
【参考方案2】:这已经很老了,但是......
在许多情况下,在 Qt Widgets 应用程序中嵌入 QML 小部件是没有用的,除非您可以在不破坏堆栈顺序的情况下使其透明。
我没有实施的解决方案,因为最后我不需要这样做。但我正在解释我的方法是什么,以防有人想尝试一下。
1) 获取具有父背景的像素图:
void QuickRoomWidget::showEvent(QShowEvent *event)
QPoint p1 = mapTo(parentWidget(), QPoint(0, 0));
QPixmap px = parent->grab(QRect(p1, size()));
2) 使用 QQuickImageProvider 在 QML 中传递图像:
https://doc.qt.io/qt-5/qquickimageprovider.html
https://doc.qt.io/qt-5/qtquick-imageprovider-example.html
3) 让你的 qml 小部件的根项使用像素图绘制背景。
当然,这样做的性能不会很好,因此取决于您需要在哪里使用它可能不是一个选择。但就我而言,这不是问题。
如果有人尝试过,请告诉我它是否有效!
【讨论】:
以上是关于无法在不中断堆叠顺序的情况下使 QQuickWidget 背景透明的主要内容,如果未能解决你的问题,请参考以下文章