起源
有网友问:
QWidget w1; QWidget w2(&w1, Qt::Window);
两个顶级窗体,前者会在任务栏显示,后者却不会,如何让后者也在任务栏显示?
首先提一下:这个效果是平台相关的,他的描述应该是Windows的结果,Linux下应该没有这个区别。
简单理理
接漫谈QWidget及其派生类(一),QWidget 中窗口可按有无parent分两种:
| primary window | 无 parent | 会自动设置Qt::Window标记 |
| secondary window | 有 parent | 对于普通的QWidget,需手动设置Qt::Window标记 |
win32
在Win32下,窗口的创建是通过CreateWindowEx完成的:
HWND WINAPI CreateWindowEx( __in DWORD dwExStyle, __in_opt LPCTSTR lpClassName, __in_opt LPCTSTR lpWindowName, __in DWORD dwStyle, __in int x, __in int y, __in int nWidth, __in int nHeight, __in_opt HWND hWndParent, __in_opt HMENU hMenu, __in_opt HINSTANCE hInstance, __in_opt LPVOID lpParam );
注意其中的参数:hWndParent 和 dwStyle
| dwStyle 指定窗口风格 | WS_OVERLAPPED 对应 Qt::Window |
| hWndParent | 自然而然对应 对应Qt中的父子关系 |
WS_OVERLAPPED 风格 + hWndParent 就是 所谓的 Owned Windows 了:
Owned Windows
An overlapped or pop-up window can be owned by another overlapped or pop-up window. Being owned places several constraints on a window.
An owned window is always above its owner in the z-order.
The system automatically destroys an owned window when its owner is destroyed.
An owned window is hidden when its owner is minimized.
Only an overlapped or pop-up window can be an owner window; a child window cannot be an owner window. An application creates an owned window by specifying the owner's window handle as the hwndParent parameter of CreateWindowEx when it creates a window with the WS_OVERLAPPED or WS_POPUP style.
涉及到的Windows api函数还有:
-
SetParent()
-
SetWindowLong()
- ...
注:Qt中相关源码见 qwidget_win.cpp 中的 QWidgetPrivate::create_sys() 及 QWidgetPrivate::setParent_sys()等
X11
在X11下,窗口的创建
Window XCreateWindow(display, parent, x, y, width, height, border_width, depth,
class, visual, valuemask, attributes)
Display *display;
Window parent;
int x, y;
unsigned int width, height;
unsigned int border_width;
int depth;
unsigned int class;
Visual *visual
unsigned long valuemask;
XSetWindowAttributes *attributes;
尽管这个也有一个parent参数,但和Win32下的含义是不同的。对于每一个顶级窗口都需要以 root 窗口为 parent (fixme)
从 Qt 源码 QWidgetPrivate::create_sys()可见到这样的片段:
parentw = topLevel ? root_win : parentWidget->effectiveWinId();
....
id = (WId)qt_XCreateWindow(q, dpy, parentw,
safeRect.left(), safeRect.top(),
safeRect.width(), safeRect.height(),
0, xinfo.depth(), InputOutput,
(Visual *) xinfo.visual(),
CWBackPixel|CWBorderPixel|CWColormap,
&wsa);
....
本文探讨了在Qt中如何使带有父窗口的二级窗口在任务栏上显示,详细解析了不同平台下窗口创建机制,包括Win32和X11的区别,并提供了具体的实现方法。
1176

被折叠的 条评论
为什么被折叠?



