zoukankan      html  css  js  c++  java
  • Qt疑难问题-模态窗口父类被析构

    最近遇到一个朋友,问了我一个刁钻的问题,当你模态弹出一个窗体时,后台把这个窗体的父类给析构了,这个时候会出现什么样的情况?

    听到问题后我真是一脸懵逼呀!从来没有这么写过代码。

    随后写了一个简单的测试demo,跟踪了下Qt的源码,得出如下结论:

    1. 首先程序不会崩溃
    2. 模态窗口会被析构并关闭

    带着这两个问题我们来研究下Qt的代码

    1、测试代码

    测试代码超级简单,就是当我们的模态窗体弹出时,使用定时器10s后析构了其父类obj对象

    QPushButton * obj = new QPushButton;
    QTimer::singleShot(10000, this, [&obj]() {
        delete obj;
        obj = nullptr;
    });
    QDialog * p = new QDialog(obj);
    p->exec();
    

    2、堆栈调用

    首先我们来看下模态窗口析构时,是由谁触发的,如下图所示,从堆栈可以很清楚的看到是父类按钮析构时,析构其所有子窗口干的。

    3、分析代码

    a、QDialog::exec

    int QDialog::exec()
    {
        ...
        QEventLoop eventLoop;
        d->eventLoop = &eventLoop;
        (void) eventLoop.exec(QEventLoop::DialogExec);
        ...
    }
    

    当我们调用QDialog的exec方法时,内部开启了一个QEventLoop事件循环

    b、QEventLoop::exec

    int QDialog::exec()
    {
        ...
        while (!d->exit.loadAcquire())
            processEvents(flags | WaitForMoreEvents | EventLoopExec);
        ...
    }
    

    这个方法里边就是一直死循环处理我们的事件,当d->exit.loadAcquire()返回不为false时,事件循环退出,也就是我们的模态窗体要关闭了。

    下面我们来分析d->exit.loadAcquire()这个接口为什么返回了真

    首先我给所有调用d->exit.storeRelease方法的地方都打了断点,发现是在QEventLoop::exit函数中命中断点,看了下调用堆栈,没毛病,一切正常。

  • 相关阅读:
    Taobao File System
    poj 1860 (Bellman_Ford判断正环)
    IOS研究院之打开照相机与本地相册选择图片
    mysql中timestamp,datetime,int类型的区别与优劣
    数学之路(3)-机器学习(3)-机器学习算法-贝叶斯定理(3)
    POJ 3740 DLX
    HDU4738【杭州网赛、判桥】
    umdh工具使用
    计算机组成与设计(八)—— 单周期处理器
    计算机组成与设计(七)—— 除法器
  • 原文地址:https://www.cnblogs.com/swarmbees/p/10867898.html
Copyright © 2011-2022 走看看