第三回 父与子
70后的道友都应该看过这么一部片子叫做<<父子情深>>。讲述的是一个小男孩患了绝症,父亲为了满足他的愿望,让已关门的游乐园为他们父子俩重新开放。在游乐园尽情地玩耍后,最后小孩子在父亲的怀中安详地闭上了眼睛。缓缓转动的摩天轮,配着淡淡忧伤的曲调,这一刻哥泪流满面。谁说世上只有妈妈好,父爱也顶半边天。此时台下的众多男道友热泪盈眶,不约而同地起立鼓掌。史上最大的冤屈,终于得以昭雪。
但是人世间这种真挚的父爱也存在于Qt中吗? 对此,从小缺乏父爱的张无忌小友给出了自己的答案,
| 04 | classMyTestA : publicQObject  | 
 
| 11 | classMyTestB : publicQObject  | 
 
| 14 |  MyTestB(QObject *parent):QObject(parent)  | 
 
| 20 | externMyTestB *g_pMyTestB;  | 
 
| 21 | externMyTestA *g_pMyTestA;  | 
 
| 22 | classMyTestC : publicQThread  | 
 
| 27 |  MyTestC():QThread(NULL)  | 
 
| 36 | intmain(intargc, char*argv[])  | 
 
| 38 |  QApplication app(argc, argv);  | 
 
| 48 |  if(a.thread() == b.thread() && a.thread()!=app.thread())  | 
 
| 50 |  qDebug()<< "Both parent and son have the same thread";  | 
 
 
 
 
从容地按下了F5之后,只见输出窗口妥妥地输出了"Both parent and son have the same thread".
在Qt中,当一个对象被移到另一个线程时,他的所有子对象也会一并转移到另外那个线程。
一人移民,全家无忧阿。在场的一些兼职移民中介的道友叹道,简直就是一个经典的家庭移民案例。不愧是家有一父,如有一宝啊。
紧接着只见张无忌,对此代码稍作了修改,
| 01 | classMyTestA : publicQObject  | 
 
| 07 | classMyTestB : publicQObject  | 
 
| 10 |  MyTestB(QObject *parent):QObject(parent)  | 
 
| 16 | externMyTestB *g_pMyTestB;  | 
 
| 17 | externMyTestA *g_pMyTestA;  | 
 
| 18 | classMyTestC : publicQThread  | 
 
| 23 |  MyTestC():QThread(NULL)  | 
 
| 29 |  g_pMyTestA->moveToThread(this);  | 
 
| 34 | MyTestB *g_pMyTestB = NULL;  | 
 
| 35 | MyTestA *g_pMyTestA = NULL;  | 
 
| 36 | intmain(intargc, char*argv[])  | 
 
| 38 |  QApplication app(argc, argv);  | 
 
 
 
 
却见output窗口打出,
"QObject::moveToThread: Current thread (0x2ff944) is not the object's thread (0x357b20).
Cannot move to target thread (0x2ff944)"
在Qt中,如果要切换对象的线程,不能到了目标线程里再调用moveToThread,此举会导致切换线程失败。
众人皆称,移民要合法,偷渡要不得啊。
就在众人嗟叹时,年轻气盛的无忌小友,又刷刷的写下了以下代码,
| 003 | classMyTestA : publicQObject  | 
 
| 010 | classMyTestB : publicQObject  | 
 
| 013 |     MyTestB(QObject *parent):QObject(parent)
 | 
 
| 018 | externMyTestB *g_pMyTestB;  | 
 
| 019 | externMyTestA *g_pMyTestA;  | 
 
| 020 | classMyTestC : publicQThread  | 
 
| 025 |     MyTestC(QObject *parent):QThread(parent)
 | 
 
| 031 | classMyTest : publicQDialog  | 
 
| 036 |     MyTest(QWidget *parent = 0, Qt::WFlags flags = 0);
 | 
 
| 046 | /////////////////////////////////////////
 | 
 
| 047 | MyTest::MyTest(QWidget *parent,Qt::WFlags flags)
 | 
 
| 048 |     :QDialog(parent, flags)
 | 
 
| 051 |     //setthe window to be the top window
 | 
 
| 052 |     <SPANstyle=
"COLOR: #ff0000">this->setWindowFlags(windowFlags()|Qt::WindowStaysOnTopHint);</SPAN>
 | 
 
| 060 | voidMyTest::onClick()  | 
 
| 062 |     <SPANstyle=
"COLOR: #ff0000">QMessageBox box(this);</SPAN>
 | 
 
| 063 |     box.setText("i am at thetop"
);  | 
 
| 067 | //////////////////main.cpp///////////////////////
 | 
 
| 068 | MyTestB *g_pMyTestB = NULL;
 | 
 
| 069 | MyTestA *g_pMyTestA = NULL;
 | 
 
| 070 | intmain(intargc, char*argv[])  | 
 
| 072 |     QApplication app(argc, argv);
 | 
 
| 078 |     <SPANstyle=
"COLOR: #ff0000">MyTestB *pB = newMyTestB(&a);</SPAN>
 | 
 
| 079 |    <SPANstyle=
"COLOR: #ff0000"> pB->setObjectName("MyTestB");</SPAN>
 | 
 
| 081 |    <SPANstyle=
"COLOR: #ff0000"> MyTestC *pC = newMyTestC(&a);</SPAN>
 | 
 
| 082 |     <SPANstyle=
"COLOR: #ff0000">pC->setObjectName("MyTestC");</SPAN>
 | 
 
| 084 |     <SPANstyle=
"COLOR: #ff0000">pC = newMyTestC(&a);</SPAN>
 | 
 
| 085 |     <SPANstyle=
"COLOR: #ff0000">pC->setObjectName("MyTestC1");</SPAN>
 | 
 
| 087 |     <SPANstyle=
"COLOR: #ff0000">QList<QObject*> list =a.findChildren<QObject*>();</SPAN>
 
 | 
 
| 088 |     QList<QObject*>::iterator it;
 | 
 
| 089 |     qDebug()<<"All the sonlist: "
<<"\r\n";
 | 
 
| 090 |     for(it = list.begin();it != list.end() ; it++)
 | 
 
| 092 |         qDebug()<<(*it)->objectName()<<"\r\n";
 | 
 
| 094 |     qDebug()<<"============================"<<"\r\n";  | 
 
| 097 |     <SPANstyle=
"COLOR: #ff0000">QList<MyTestC*> listC =a.findChildren<MyTestC*>();</SPAN>
 
 | 
 
| 098 |     QList<MyTestC*>::iterator itC;
 | 
 
| 099 |     qDebug()<<"MyTestC list:"
<<"\r\n";
 | 
 
| 100 |     for(itC = listC.begin();itC != listC.end() ; itC++)
 | 
 
| 102 |         qDebug()<<(*itC)->objectName()<<"\r\n";
 | 
 
| 104 |     qDebug()<<"============================"<<"\r\n";  | 
 
| 106 |    <SPANstyle=
"COLOR: #ff0000"> MyTestC *pC1 = a.findChild<MyTestC*>("MyTestC1");</SPAN>
 | 
 
| 109 |         qDebug()<<"MyTestC1 hasbeen found"
<<"\r\n";
 | 
 
 
 
 
然后销魂的转身一点,只见

在Qt中,我们可以通过findChild,findChildren,qFindChild,qFindChildren,来遍历所有的子对象,同时我们可以通过指定类型,来得到所有的指定类型的子对象,当然也可以通过对象名字来索引。比如m_dlg.findChildren<QPushButton*>();通过这个函数我们可以轻松的遍历出对话框中所有的QPushButton子对象,这样对我们诸如换语言的操作提供了便利。换句话说,Qt的父对象也起到了一个容器的作用,我们有时可以利用这一点,把父对象作为一个容器处理。
众人不禁赞道,知子莫如父啊。
无忌小友看在眼里,喜在心头。只见他又继续点击F5,弹出了一个对话框,

此对话框设置了Top属性,使之能够在所有其它应用程序窗口之上(this->setWindowFlags(windowFlags()|Qt::WindowStaysOnTopHint);)。然后又点击了PushButton,弹出了一子对话框。只见子对话框也自动继承了父窗口的属性,成为了Top window。
在Qt中,我们只需在父窗口设置某些属性(比如Top,bottom),子窗口将自动获得这些属性,使开发者不用为了保持子窗口与父窗口的一致性,每个窗口一个一个去设置。提高了开发效率。
众人皆叹,有父如此,子欲何求。老子干活,儿子享福啊。此时一股浓浓的父爱弥漫在武当大殿中。谁说父爱不顶半边天?此时的男道友们心潮澎湃,激动之余不禁拨通了"流言终结者"的制作组电话。
而反观另外一些道友,眼看她们引以为傲的优势,将被击得荡然无存。她们不甘心失败,一遍遍的看着代码,企图找出一丝破绽来。终于,一位女道友面带冷笑,指着代码说道,“无忌道友,此程序好似有内存泄露,不知对否”。众人心头一紧,Qt往日的无耻又浮现在了人们心头。
但见无忌小友手持羽扇,迎风而立,露出招牌般的正太式微笑,徐徐说道,“早知道友会有此一问。”接着从怀中取出一本写有”九阳真经“的古籍,翻了开来。只见一幅制作精美具有扶桑画风的彩图映入了众人的眼帘,图下面写着”伴我成长的女人们“。张无忌脸色一红,尴尬地咳嗽了一声,又继续翻到了下一页,只见上面写着,
| 05 |     if(!d->children.isEmpty())
 | 
 
| 11 | voidQObjectPrivate::deleteChildren()
 | 
 
| 13 |     constboolreallyWasDeleted = wasDeleted;
 | 
 
| 15 |     //delete children objects
 | 
 
| 16 |     //don't use qDeleteAll as the destructor of the child might
 
 | 
 
| 18 |     for(inti = 0; i <children.count(); ++i) {
 | 
 
| 19 |         currentChildBeingDeleted = children.at(i);
 | 
 
| 21 |         deletecurrentChildBeingDeleted;
 | 
 
| 24 |     currentChildBeingDeleted = 0;
 | 
 
| 25 |     wasDeleted = reallyWasDeleted;
 | 
 
 
 
 
在Qt中,当以QObject为父类的对象析构时,他会自动删除它所包含的所有子对象,实现了简单的垃圾回收机制,避免了内存泄露。所以开发时可以考虑,每个new出来的对象尽量设置父对象,这样即使未显示调用delete,只要保证父对象被析构,就能避免内存泄露。
武当大殿沸腾了,观众们被Qt父子情深般的精彩表演深深震撼了。”学Qt,得永生“的口号响彻云霄(春哥泪流满面)。《流言终结者》主持人杰米和亚当宣布,人类史上最大的流言"父子不如X子亲"终结了。节目赞助商Intel鉴于此期节目在CCAV上99.99%的收视率,以4.44亿RMB天价强行插入了一条广告“Intel,给Qt一颗奔腾的芯”。
而Qt的代言人无忌小友,获得了道教界一年一度以道家镇教之宝命名的,最高荣誉“八卦”奖。当从道教最高精神领袖“张三丰”手中接过雕有“冠希”前辈手拿camera的小金像,正要发表获奖感言的时侯,一道剑光闪过。
正所谓伯乐不常有,但搅屎棍却常在。
只见人见人怕,鬼见鬼愁,考试只给59分的灭绝师太,手握倚天剑,刷刷的修改了张无忌的代码。
| 01 | classMyTestA : publicQObject  | 
 
| 07 | classMyTestB : publicQObject  | 
 
| 10 |     MyTestB(QObject *parent):QObject(parent)
 | 
 
| 16 | externMyTestB *g_pMyTestB;  | 
 
| 17 | externMyTestA *g_pMyTestA;  | 
 
| 18 | classMyTestC : publicQThread  | 
 
| 23 |     MyTestC():QThread(NULL)
 | 
 
| 34 | MyTestB *g_pMyTestB = NULL;
 | 
 
| 35 | MyTestA *g_pMyTestA = NULL;
 | 
 
| 36 | intmain(intargc, char*argv[])  | 
 
| 38 |     QApplication app(argc, argv);
 | 
 
 
 
 
执行此段代码后,众人皆惊。只见output窗口输出了“QObject::moveToThread: Cannot move objects with a parent”。
灭绝师太斜眼冷笑道:“黄口小儿,安能善言人伦乎? “
由此可见Qt中,子对象不能脱离父对象,单独切换到与父对象不同的线程中。
此时的张无忌面色惨白。但灭绝师太誓将张无忌搞臭到底,以不负灭绝的美名。只见她又修改了一段代码,
| classMyTestA : publicQObject  | 
 
| classMyTestB : publicQObject  | 
 
|     MyTestB(QObject *parent):QObject(parent)
 | 
 
| externMyTestB *g_pMyTestB;  | 
 
| externMyTestA *g_pMyTestA;  | 
 
| classMyTestC : publicQThread  | 
 
| MyTestB *g_pMyTestB = NULL;
 | 
 
| MyTestA *g_pMyTestA = NULL;
 | 
 
| intmain(intargc, char*argv[])  | 
 
|     QApplication app(argc, argv);
 | 
 
|     MyTestA*pA =
newMyTestA;  | 
 
|     MyTestB*pB =
newMyTestB(pA);  | 
 
 
 
 
只见程序蹦出了警告对话框,

程序直接崩溃了。与之同时崩溃的,还有众男道友的心。
而张无忌啪跌坐在地上,万念俱灰。与霆锋哥相拥痛哭,为什么上一辈的悲剧,又在我们身上重演。
对于Qt子对象而言,不能在父对象删除后,再删除自己。因为父对象析构时,会删除所有的子对象,此时子对象再删除,会引起二次析构。
所以如果子对象要切换到另一个线程或者避免被父对象删除,则需要调用setParent(NULL),解除父子关系。
灭绝师太仰天长笑道“Qt名为父子,实乃黑帮。”
太史公评曰:“一入Q门深似海,从此萧郎是路人”。
瑟瑟风中,只见张无忌将自己多年的呕心力作<<我与Qt之间不得不说的故事>>付之一炬,飘然而去。从此之后,弃码从武,苦练九阳真经,终成一代大侠,名满江湖,这当然都是后话。
欲知后事如何,请听下回分解。
												
												
								- OpenCascade拓扑对象之:TopoDS_Shape对象及其子对象
		@font-face { font-family: "Times New Roman" } @font-face { font-family: "宋体" } @ ... 
- Qt——父对象、布局
		设置父对象两个好处:(1)加入析构树(2)和父对象一起显示 设置布局后,子控件自动被设置父对象 设置父对象两个好处:(1)加入析构树(2)和父对象一起显示 
- Qt Quick 组件和动态创建的对象具体的解释
		在<Qt Quick 事件处理之信号与槽>一文中介绍自己定义信号时,举了一个简单的样例.定义了一个颜色选择组件,当用户在组建内点击鼠标时,该组件会发出一个携带颜色值的信号,当时我使用 Co ... 
- Qt 对象间的父子关系
		C++中只要有一个new就必须要有一个delete与之对应 但是Qt中的对象之间有特殊的关系 Qt 对象间的父子关系 每一个对象都保存有它所有子对象的指针 每一个对象都有一个指向其父对象的指针 par ... 
- 3dsmax不同版本 pyside qt UI 设置max窗口为父窗口的方法
		3dsmax不同版本 pyside qt widget 设置 max 窗口为父窗口的方法 前言: 3dsmax 在 2014 extension 之后开始集成 Python 和 PySide,但是在版 ... 
- Qt DLL总结【三】-VS2008+Qt 使用QPluginLoader访问DLL
		目录 Qt DLL总结[一]-链接库预备知识 Qt DLL总结[二]-创建及调用QT的 DLL Qt DLL总结[三]-VS2008+Qt 使用QPluginLoader访问DLL 开发环境:VS20 ... 
- Qt DLL总结【二】-创建及调用QT的 DLL(三篇)good
		目录 Qt DLL总结[一]-链接库预备知识 Qt DLL总结[二]-创建及调用QT的 DLL Qt DLL总结[三]-VS2008+Qt 使用QPluginLoader访问DLL 开发环境:VS20 ... 
- jquery获取元素的值,获取当前对象的父对象等等
		jsp代码: <span><input type="hidden" value="1" id="newInfo">& ... 
- javascript --- 子对象访问父对象的方式
		在传统面向对象的编程语言里,都会提供一种子类访问父类的特殊语法,引文我们在实现子类方法往往需要父类方法的额外辅助.在这种情况下,子类通常会调用父类中的同名方法,最终以便完成工作. javascript ... 
随机推荐
	
									- HTML 5浏览器端数据库
			HTML 5浏览器端数据库为什么要使用浏览器端数据库:随着浏览器处理能力的增强,越来越多的双喜鸟网站开始考虑在客户端存储大量的数据,这可以减少用户从服务器获取数据的等待时间. 1.本地存储-本地存储可 ... 
- 【转】js原型链与继承
			原文链接:https://blog.csdn.net/u012468376/article/details/53127929 一.继承的概念  继承是所有的面向对象的语言最重要的特征之一.大部分的o ... 
- You are using the runtime-only build of Vue where the template compiler is not available.
			使用vue-cli搭建的项目,启动报错 You are using the runtime-only build of Vue where the template compiler is not a ... 
- Heap(堆)与Stack(栈)的区别详解
			在了解堆与栈之前,我们想来了解下程序的内存分配 一个编译的程序占用的内存分为以下几个部分  :  1.栈区(stack)—   由编译器自动分配释放   ,存放函数的参数值,局部变量的值等.其     ... 
- Java动态追踪技术探究(动态修改)
			Java动态追踪技术探究 Java探针-Java Agent技术-阿里面试题 秒懂Java动态编程(Javassist研究) 可以用于在类加载的时候,修改字节码. Java agent(Java探针) ... 
- String s=new String("xyz");创建了几个String Object?二者之前的区别是什么?
			两个.第一个对象是字符串常量"xyz",第二个对象是new String("xyz")的时候产生的,在堆中分配内存给这个对象,只不过这个对象的内容是指向字符串常 ... 
- 使用FindCmdLineSwitch处理命令行参数
			一.四个形式(变体) .function FindCmdLineSwitch(const Switch: string; const Chars: TSysCharSet; IgnoreCase: B ... 
- Django—跨域请求
			同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 而如果我们要跳过这个策略,也就是说非要跨域请求,那么就需要通过J ... 
- NUC970 Linux CAN 驱动问题及解决办法之二
			开发平台介绍: NUC970 + 内置CAN控制器(双通道CAN1\CAN2) + 官方Linux_Kernel(少量修改) 名词: 终端,使用NUC970的硬件 异常表现: 1.当CAN收发器(VP ... 
- iview 如何在表格中给操作图标添加Tooltip文字提示?
			项目需要用到的iview 表格中操作项目有各种各样的图标,而各种各样的图标代表不同的操作,面对新用户可能很懵,那如何给这些图标添加Tooltip文字提示? 废话不多讲,直接看代码: <templ ...