QWidget 之 Secondary Windows 小记

晨曦之光 发布于 2012/05/08 10:16
阅读 245
收藏 0
Qt

起源

有网友问:

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

参考


原文链接:http://blog.csdn.net/dbzhang800/article/details/6817630
加载中
返回顶部
顶部