无法在不中断堆叠顺序的情况下使 QQuickWidget 背景透明

Posted

技术标签:

【中文标题】无法在不中断堆叠顺序的情况下使 QQuickWidget 背景透明【英文标题】:Unable to make QQuickWidget background transparent without break stacking order 【发布时间】:2017-01-17 11:42:51 【问题描述】:

我在使 QQuickWidget 背景透明时遇到问题。

我想在QWidget 下方放置一个QQuickWidgetQQuickWidget 使用源 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 下方的其他小部件的堆叠顺序。

我想让QQuickWidgetQWidget 下方时透明。这可能吗?如果没有,您建议什么解决方法?

(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.pngsemitransparent.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 背景透明的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在不重新编译的情况下使科尔多瓦应用程序可调试?

如何在不滚动的情况下使此页眉和页脚可见?

如何在不给定高度的情况下使内容在弹性框中可滚动?

如何在不使用滤镜的情况下使图像变暗? [复制]

如何在不需要额外点击的情况下使 DataGridCheckBoxColumn 可编辑?

如何在不使用 div 的情况下使 iframe 响应?