You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Windows自定义桌面(HDESK)上显示QDialog

问题描述

我在Windows平台开发Qt项目时,需要调用CreateDesktop、OpenDesktop、SwitchDesktop等Win32 API创建自定义桌面(HDESK),原本计划按需调用exec或show方法在新桌面上展示QDialog,但实际运行时QDialog并未显示在新创建的桌面,反而出现在系统默认桌面上。

原有实现代码大致如下:

/* 从main函数启动QApplication */
QApplication qApp;
qApp.exec();
/* [...] 事件触发或收到Win32 COM调用,通知需要展示QDialog */
/* 创建新桌面并切换 */
HDESK hNewDesktop=NULL;

hNewDesktop=CreateDesktop(L"_MyNewDesktopName", NULL, NULL, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, NULL);
SwitchDesktop(hNewDesktop);

/* 创建并展示QDialog */
QDialog *pqdlgMyDialog=NULL;

pqdlgMyDialog=new QDialog(NULL);
pqdlgMyDialog->show(); // 根据需求也可调用.exec()

按照上述代码运行时,虽然能成功创建并切换到黑色背景的新桌面,但QDialog始终显示在Windows启动后默认加载的系统桌面上。

我也曾尝试通过如下方式为QDialog设置父窗口,但该方案同样无效:

QWindow *pqwParentWindow=NULL;
QWidget *pwqParentWidget=NULL;
HWND hwndParentWindow=NULL;

hwndParentWindow=GetTopWindow(NULL); // 也尝试过GetDesktopWindow、FindWindowEx等接口
pqwParentWindow=QWindow::fromWinId((WId)hwndParentWindow);
pwqParentWidget=QWidget::createWindowContainer(pqwParentWindow);
[...]
QDialog *pqdlgMyDialog=NULL;
pqdlgMyDialog=new QDialog(pwqParentWidget);
pqdlgMyDialog->show(); // 根据需求也可调用.exec()

我查阅了大量Qt官方文档与MSDN资料,尝试查找“QApplication是否与特定桌面绑定”等相关内容,但始终未找到有效解决方案。

解决方案

经过多轮测试并结合社区提供的有效思路,现已确认必须在创建QApplication实例之前调用SetThreadDesktop接口,这是让Qt能够在新桌面正常显示QWidget组件的唯一方式。

SwitchDesktop接口可在QApplication创建前后任意时机调用,只要保证SetThreadDesktop的调用早于QApplication创建即可。

希望该内容能为其他开发者提供参考。


内容的提问来源于stack exchange,提问作者JayDee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 18:33:31