您的位置:首页 > 其它

QWidget 之 Secondary Windows 小记

2011-09-24 16:37 363 查看


起源

有网友问:
QWidget w1;
QWidget w2(&w1, Qt::Window);


两个顶级窗体,前者会在任务栏显示,后者却不会,如何让后者也在任务栏显示?
首先提一下:这个效果是平台相关的,他的描述应该是Windows的结果,Linux下应该没有这个区别。


简单理理

漫谈QWidget及其派生类(一),QWidget
中窗口可按有无parent分两种:

primary window
无 parent
会自动设置Qt::Window标记
secondary window
有 parent
对于普通的QWidget,需手动设置Qt::Window标记

对于QMainWindow及QDialog,其构造函数中已经设置了该标记,故可以直接用


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);
....



参考

MSDN
CreateWindowEx function

MSDN
Owned Windows

http://tronche.com/gui/x/xlib/window/XCreateWindow.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: