有网友问:
QWidget w1; QWidget w2(&w1, Qt::Window);
两个顶级窗体,前者会在任务栏显示,后者却不会,如何让后者也在任务栏显示?
首先提一下:这个效果是平台相关的,他的描述应该是Windows的结果,Linux下应该没有这个区别。
接漫谈QWidget及其派生类(一),QWidget 中窗口可按有无parent分两种:
primary window |
无 parent |
会自动设置Qt::Window标记 |
secondary window |
有 parent |
对于普通的QWidget,需手动设置Qt::Window标记 |
在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下,窗口的创建
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); ....
MSDN CreateWindowEx function
MSDN Owned Windows
http://tronche.com/gui/x/xlib/window/XCreateWindow.html