漫谈QWidget及其派生类(一)

原文地址: https://blog.csdn.net/dbzhang800/article/details/6737540

对于QWidget,总觉得该写点什么。可又不知道具体该写些什么,思路又乱又杂。简单理理,简单写写,就叫漫谈吧

注意:我不知道本文写完会是什么样子,可能写着写着就没下文了。也可能各部分隔很长时间。

注意:本系列涉及到的东西都是Qt用户需要理解的,但是,我们不应该在实际项目中这么用。

QWidget


QWidget 是Qt中所有widget部件(比如QDialog、QPushButton、QLabel)的基类。

  • 任何你可以通过其派生类实现的东西,你都可以通过QWidget实现(只要你不怕麻烦)\比如

比如:

QDialog有模态非模态之说 QWidget 有没有?当然有,不要怀疑
QDialog dlg(this)是一个窗口 QWidget wgt(this)能不能是窗口?当然行
QMainWindow可以有菜单栏、工具栏等 QWidget 可不可以加?当然可以,只要你需要
... ...

Window 与 Widget


Qt中的部件有Window和普通widget之说:
|QDialog有模态非模态之说|QWidget 有没有?当然有,不要怀疑|

Window 窗口 Window是这样的Widget:它不是其他Widget的一部分区域,通常有标题栏等窗口装饰器!(和是否有parent无关)
Widget 普通部件(非窗口) 除Window外的部件

如何可以知道一个widget是否是Window?注意:QWidget::isWindow()

inline bool QWidget::isWindow() const
{ return (windowType() & Qt::Window); }

呵呵,不小心将源码给出了,那就继续吧,

windowType() 是什么东西?为了避免混乱,我将它和windowFlags()同等看待(其中的细微区别不会影响我们的分析)

看看下面的函数:

QWidget::QWidget(QWidget * parent = 0, Qt::WindowFlags f = 0 )
void QWidget::setWindowFlags(Qt::WindowFlags type )
QDialog::QDialog(QWidget * parent = 0, Qt::WindowFlags f = 0 )
...

恩,你可以通过构造函数或者成员函数setWindowFlags传递这个参数。 而且,你从前面的isWindow()的源码可以得出结论: 一个Widget是不是一个Window,只取决于它的的WindowFlags中是否包含Qt::Window

对么??


你会不会说:不对!!!

  • 例子一
    比如:一个QPushButton,如果没有parent,它就是一个窗口。而设置了parent,它却不是一个窗口了。分明就是和是否有parent相关嘛!(这种例子太常见了,对吧)

  • 例子二
    恩,再看一个很多人迷惑的例子:在一个函数内

void Widget::onXXXX()
{
     QDialog * dlg = new QDialog(this);
     //QWidget * dlg = new QWidget(this);
     dlg->show();
}

如果用 QDialog,则会出现一个窗口,而如果用 QWidget,则不会出现窗口(而是一个普通部件)。为什么啊?都有parent啊?为什么会这样??

其实:例子一是特例,原因就是前面提到的,是否是窗口取决于flags,而不是有无parent

原因


记住前面的黑体部分!

对于QWidget,如果其parent为空,构造时会有下面的动作:

    uint type = (flags & Qt::WindowType_Mask);

    if ((type == Qt::Widget || type == Qt::SubWindow) && w && !w->parent()) {
        type = Qt::Window;
        flags |= Qt::Window;
    }

注意看,如果一个widget没有parent,且没有Qt::Window标记,会被强制设置该标记(如果有parent,就不会设置标记了)。这就是parent的影响,也是上面例子一的答案。

可是第二个例子怎么回事?QDialog默认的flags也是0啊,也就parent,为啥还是窗口呢??

QDialog::QDialog(QWidget *parent, Qt::WindowFlags f)
    : QWidget(*new QDialogPrivate, parent,
              f | ((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0)))
{
...

答案很简单,QDialog是派生类嘛,它构造函数中传给基类的参数包含了Qt::Dailog(即0x00000002|Qt::Window)。既然包含了Qt::Widnow标记,当然就和是否有parent无关喽!(例子一其实才是特例,只不过大家见的多了,反倒习以为常了)

  • 例子三
    感兴趣的看看,会有什么结果,嘿嘿,本节完
QPushButton * btn = new QPushButton(this);
btn->setWindowFlags(Qt::Window);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容