QWidget的hide()方法在IVI Wayland合成器中销毁Surface的问题咨询
IVI合成器中QWidget hide()销毁Surface的问题解答
问题描述
基于Qt的IVI合成器示例实现了自定义合成器,期望通过Surface的visible属性控制窗口可见性。但当客户端调用QWidget的hide()方法时,合成器会直接销毁Surface,而非仅将visible属性设为false。
结论
这是Qt Wayland客户端结合ivi-shell使用时的预期行为。Qt Widget框架在Wayland平台下,默认会在窗口隐藏时销毁对应Wayland Surface——这符合Wayland“仅保留需要显示的Surface”的设计理念,而ivi-shell的默认集成逻辑并未覆盖这一行为。
修改方法
1. 客户端侧快速调整(推荐)
启动Qt Widget客户端前,设置环境变量:
export QT_WAYLAND_HIDE_DESTROYS_SURFACE=0
该变量会强制Qt客户端在窗口隐藏时保留Surface,仅向合成器发送可见性变更信号,此时合成器即可通过监听ivi-surface的visible属性变化来控制显示状态。
2. 自定义ivi-shell集成(进阶)
若需更精细的控制逻辑,可在客户端自定义Wayland shell集成:
- 继承
QWaylandShellIntegration,实现针对ivi-shell的专属处理逻辑; - 重写窗口的
hideEvent和showEvent,通过ivi-application协议主动设置ivi-surface的visible属性,替代Qt默认的Surface销毁逻辑; - 将自定义集成编译为Qt Wayland插件并注册使用。
复现步骤
- 编译并运行Qt官方的IVI合成器示例
- 在Qt Creator中创建新的Qt Widgets项目,保留所有默认设置
- 修改
mainwindow.h代码:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTimer> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; QTimer *pTimer; private slots: void hideWindow(); }; #endif // MAINWINDOW_H
- 修改
mainwindow.cpp代码:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); pTimer = new QTimer(); pTimer->setInterval(1000); connect(pTimer, SIGNAL(timeout()), this, SLOT(hideWindow())); pTimer->start(); } void MainWindow::hideWindow() { if (isVisible()) { qDebug() << "hide!"; hide(); } else { qDebug() << "show!"; show(); } } MainWindow::~MainWindow() { delete ui; }
- 编译运行客户端前,需设置环境变量:
QT_WAYLAND_SHELL_INTEGRATION=ivi-shellQT_IVI_SURFACE_ID=1337- (若使用第一种修改方法,需额外添加
QT_WAYLAND_HIDE_DESTROYS_SURFACE=0)
内容的提问来源于stack exchange,提问作者klauskleber
相关产品推荐
相关产品推荐

