QWidget 之 Secondary Windows 小记

13 篇文章 5 订阅

起源

有网友问:

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

参考

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值