Невозможно сделать фон QQuickWidget прозрачным без порядка наложения

У меня проблема с QQuickWidget фон прозрачный.

Я хочу разместить QQuickWidget под QWidget, 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 как ложь:

(6) Что я получу, когда установлю WA_AlwaysStackOnTop как правда:

1 ответ

Это довольно старый, но...

Во многих случаях встраивание виджета QML в приложение Qt Widgets бесполезно, если вы не можете сделать его прозрачным, не нарушая порядок стеков.

У меня нет реализованного решения, так как в итоге мне не нужно было это делать. Но я объясняю, каков был мой подход на случай, если кто-то захочет попробовать.

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 нарисовать фон с помощью растрового изображения.

Конечно, производительность выполнения этого не будет большой, поэтому, в зависимости от того, где вам нужно ее использовать, это, вероятно, не вариант. Но в моем случае это не было проблемой.

Если кто-то попробует, пожалуйста, дайте мне знать, сработало ли это!

Официальная документация QT здесь http://doc.qt.io/qt-5/qquickwidget.html говорит, что следует ожидать нарушения порядка размещения:

Когда это абсолютно необходимо, это ограничение можно преодолеть, установив атрибут Qt::WA_AlwaysStackOnTop в QQuickWidget. Имейте в виду, однако, что это нарушает порядок наложения. Например, не будет возможности иметь другие виджеты поверх 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.

Мой совет: не пытайтесь решить эту проблему с помощью взлома, но измените подход к пользовательскому интерфейсу. Например, может быть, вы можете сделать topWidget альфа-смесь (полупрозрачная).

РЕДАКТИРОВАТЬ: Например, вот так:

введите описание изображения здесь

Другие вопросы по тегам