当前位置: 首页 > news >正文

呼图壁网站建设跨境电商软件平台

呼图壁网站建设,跨境电商软件平台,表白网页在线生成制作源码,网站上面添加地图对象树管理 个人经验总结#xff0c;如有错误或遗漏#xff0c;欢迎各位大佬指正 #x1f603; 文章目录对象树管理设置父对象的作用设置父对象(setParent)完整源码片段分析对象的删除夹带私货时间设置父对象的作用 众所周知#xff0c;Qt中#xff0c;有为对象设置父对象…对象树管理 个人经验总结如有错误或遗漏欢迎各位大佬指正 文章目录对象树管理设置父对象的作用设置父对象(setParent)完整源码片段分析对象的删除夹带私货时间设置父对象的作用 众所周知Qt中有为对象设置父对象的方法——setParent。 而设置父对象的作用主要有在父对象析构的时候会自动去析构其子对象。如果是一个窗口对象如果其父对象设置了样式表(Style Sheet)子对象也会继承父对象的样式。 所以这篇文章咱们主要看一下setParent的源码以及QObject是怎么进行对象管理的。 设置父对象(setParent) 我们可以看到setParent这个函数就是调用了QObjectPrivate类的setParent_helper这个函数。 void QObject::setParent(QObject *parent) {Q_D(QObject);Q_ASSERT(!d-isWidget);d-setParent_helper(parent); }所以我们进一步分析setParent_helper这个函数 完整源码 void QObjectPrivate::setParent_helper(QObject *o) {Q_Q(QObject);// 不能把自己设为父对象Q_ASSERT_X(q ! o, Q_FUNC_INFO, Cannot parent a QObject to itself); #ifdef QT_DEBUG// 检查对象树的循环const auto checkForParentChildLoops qScopeGuard([](){int depth 0;auto p parent;while (p) {if (depth CheckForParentChildLoopsWarnDepth) {qWarning(QObject %p (class: %s, object name: %s) may have a loop in its parent-child chain; this is undefined behavior,q, q-metaObject()-className(), qPrintable(q-objectName()));}p p-parent();}}); #endif// 如果要设置的父对象就是当前的父对象直接返回if (o parent)return;if (parent) {QObjectPrivate *parentD parent-d_func();if (parentD-isDeletingChildren wasDeleted parentD-currentChildBeingDeleted q) {// dont do anything since QObjectPrivate::deleteChildren() already// cleared our entry in parentD-children.} else {const int index parentD-children.indexOf(q);if (index 0) {// were probably recursing into setParent() from a ChildRemoved event, dont do anything} else if (parentD-isDeletingChildren) {parentD-children[index] 0;} else {// 如果对象已经存在父对象的列表中将原先存在的对象删除并发送事件parentD-children.removeAt(index);if (sendChildEvents parentD-receiveChildEvents) {QChildEvent e(QEvent::ChildRemoved, q);QCoreApplication::sendEvent(parent, e);}}}}// 设置父对象parent o;if (parent) {// object hierarchies are constrained to a single threadif (threadData ! parent-d_func()-threadData) {qWarning(QObject::setParent: Cannot set parent, new parent is in a different thread);parent nullptr;return;}// 父对象添加子对象并发送事件parent-d_func()-children.append(q);if(sendChildEvents parent-d_func()-receiveChildEvents) {if (!isWidget) {QChildEvent e(QEvent::ChildAdded, q);QCoreApplication::sendEvent(parent, e);}}}if (!wasDeleted !isDeletingChildren declarativeData QAbstractDeclarativeData::parentChanged)QAbstractDeclarativeData::parentChanged(declarativeData, q, o); }片段分析 一些先决条件的判断 判断设置的父对象是否是自己 // 不能把自己设为父对象 Q_ASSERT_X(q ! o, Q_FUNC_INFO, Cannot parent a QObject to itself); /*...*/ // 如果要设置的父对象就是当前的父对象直接返回 if (o parent) return;判断原来的父对象是否处于正在删除子对象的过程中并且当前对象已经被删除了如果是则什么都不做有点迷惑 if (parentD-isDeletingChildren wasDeleted parentD-currentChildBeingDeleted q) {// dont do anything since QObjectPrivate::deleteChildren() //already cleared our entry in parentD-children.}判断是不是通过从ChildRemoved事件递归到setParent() if (index 0) { // were probably recursing into setParent() from a ChildRemoved event,// dont do anything } else if (parentD-isDeletingChildren) { parentD-children[index] 0; }判断对象是不是已存在父对象的列表中如果存在就将对象删除并发送事件 else { // 如果对象已经存在父对象的列表中将原先存在的对象删除并发送事件 parentD-children.removeAt(index); if (sendChildEvents parentD-receiveChildEvents) { QChildEvent e(QEvent::ChildRemoved, q);QCoreApplication::sendEvent(parent, e); } }设置父对象这里有一个限制就是新设置的父对象必须和当前对象在同一个线程否则不能设置。 // 设置父对象parent o;if (parent) {// object hierarchies are constrained to a single threadif (threadData ! parent-d_func()-threadData) {qWarning(QObject::setParent: Cannot set parent, \new parent is in a different thread);parent nullptr;return;}// 父对象添加子对象并发送事件parent-d_func()-children.append(q);if(sendChildEvents parent-d_func()-receiveChildEvents) {if (!isWidget) {QChildEvent e(QEvent::ChildAdded, q);QCoreApplication::sendEvent(parent, e);}}}对象的删除 然后就是对象的管理也就是在父对象析构的时候自动析构掉所有的子对象。这一个在我们使用窗口部件的时候很有用因为一个界面可能有很多个子控件比如按钮、label等这时候如果一个小窗口被关闭我们也不需要一个一个的去析构由Qt的对象树去进行析构就好了。 QObject::~QObject() {/*...*/// 删除子对象if (!d-children.isEmpty())d-deleteChildren();#if QT_VERSION 0x60000qt_removeObject(this); #endifif (Q_UNLIKELY(qtHookData[QHooks::RemoveQObject]))reinterpret_castQHooks::RemoveQObjectCallback(qtHookData[QHooks::RemoveQObject])(this);Q_TRACE(QObject_dtor, this);if (d-parent) // remove it from parent objectd-setParent_helper(nullptr); }将所有的子对象进行删除遍历容器按照子对象所加入进来的顺序进行析构。 void QObjectPrivate::deleteChildren() {// 清空子对象Q_ASSERT_X(!isDeletingChildren, QObjectPrivate::deleteChildren(), isDeletingChildren already set, did this function recurse?);isDeletingChildren true;// delete children objects// dont use qDeleteAll as the destructor of the child might// delete siblingsfor (int i 0; i children.count(); i) {currentChildBeingDeleted children.at(i);children[i] 0;delete currentChildBeingDeleted;}children.clear();currentChildBeingDeleted nullptr;isDeletingChildren false; }夹带私货时间 在使用Qt的对象树这个功能的时候可能会遇到一种问题会导致程序崩溃就是手动的管理(也就是直接delete)一个有父对象的QObject为什么会出现这样的情况呢因为你在delete子对象之后并没有把这个对象从父对象的对象树里移除。在父对象进行析构的时候还是会去遍历子对象容器一个一个析构。这个时候就会出现一个对象指针被删除了两次自然就会崩溃。 那么如果非要自己管理这个对象有什么办法呢我们从对象树下手有两种办法 使用deleteLater 就是调用QObject对象的deleteLater函数来实现删除。关于deleteLater的分析可以看这个大佬的文章Qt 中 deleteLater() 函数的使用 QObject *object new QObject(); QObject *m_child new QObject(object);// 需要手动删除的时候 m_child-deleteLater();先将父对象设置为空再直接delete QObject *object new QObject(); QObject *m_child new QObject(object);// 需要手动删除的时候 m_child-setParent(nullptr); delete m_child; m_child nullptr;先将父对象设置为空再直接delete QObject *object new QObject(); QObject *m_child new QObject(object);// 需要手动删除的时候 m_child-setParent(nullptr); delete m_child; m_child nullptr;个人建议使用第一种方法也就是调用deleteLater
http://www.w-s-a.com/news/454438/

相关文章:

  • 龙岗商城网站建设教程百度关键词排名突然没了
  • 深圳网站建设服务哪家有织梦网站模板安装
  • 网站设计与网页制作代码大全网站开发还找到工作吗
  • 给设计网站做图会字体侵权吗站长工具seo综合查询张家界新娘
  • 网站的建设与颜色搭配win7在iis中新建一个网站
  • 单位做网站有哪些功能型类的网站
  • 网站怎样做优惠卷移动互联网开发培训
  • 重庆网站建设帝维科技网站做定向的作用
  • 网站建设工作室wp主题模板做污事网站
  • 网站建设 深圳 凡科重庆家居网站制作公司
  • 自己也可以免费轻松创建一个网站企业收录网站有什么用
  • 帮别人做网站违法导航网站开发工具
  • seo网站外包公司字画价格网站建设方案
  • 网站国内空间价格销售技巧
  • 广安建设企业网站qq互联网站备案号
  • 京东网站建设的要求vs2010做的网站
  • wordpress 新闻杂志主题佛山企业网站排名优化
  • 选服务好的网站建设金华市开发区人才网
  • 广州建站商城南阳高质量建设大城市网站
  • 网站建设合同封面模板做代炼的网站
  • 外贸网站建站要多少钱南昌优化排名推广
  • 做公司网站的尺寸一般是多大企业管理网站
  • 苏州网站设计公司兴田德润i简介做签证宾馆订单用啥网站
  • 网站页面设计工具做网站租空间
  • 做智能网站系统百度提交入口
  • 网站建设代理商电话网站规划和建设方案
  • 双桥区网站制作seo 首页
  • 电子商务网站建设前期准备wordpress域名指向二级目录
  • 汕头建站网站模板淮北做网站电话
  • 手机做logo用什么网站服务器安全防护