Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

I closed a dialog, but it seems to be still running



  • I used some global variables in that file. I also used qtimer and some time-delayed event in that code. It seems to me that the programs are still running even after I closed the dialog window (main window still running).

    After I reopened the dialog, those global variables still hold the same value. They are not refreshed.
    I set a breakpoint inside the code and the program will still pauses after some time. I guess that's the timer event.
    I also set a breakpoint in the destructor. But it never ran, even if I close the whole application.

    What's the problem?


  • Lifetime Qt Champion

    @MasterBlade said in I closed a dialog, but it seems to be still running:

    I used some global variables in that file

    Why global variables?!
    What file?

    Please show your code at least.



  • @jsulm said in I closed a dialog, but it seems to be still running:

    @MasterBlade said in I closed a dialog, but it seems to be still running:

    I used some global variables in that file

    Why global variables?!
    What file?

    Please show your code at least.

    It's a large file so I'll make it short. Just some global integers like
    int gid = 0;
    This is at the top of the .cpp file, followed by regular class definition.

    A::A(QWidget* parent) :
        QDialog(parent),
        ui(new Ui::A){
    gid = 5;
    }
    

    There are other functions that further increases gid. like ++gid; When I close that window while gid is 7 and reopen it, gid is still 7. It's neither 0 or 5.

    Also I have a qtimer, it will do something when time expired.

    connect(timer, &QTimer::timeout, this, &A::something);
    

    I set a breakpoint at 'something'. The program will still pause at 'something' even if I close the window as if it's still running.

    I also set a breakpoint at the destructor of the window. But it never runs, even if I close the whole application.



  • @MasterBlade
    It sounds like your int gid; is what you say, a global variable, not a member of your A class. So it has nothing to do with your class instances, and so will retain its value.

    Closing/re-opening a QWidget is not the same thing as new/delete-ing it, so it would not reset a member variable anyway. Unless you set Qt::WA_DeleteOnClose.

    Don't know about your breakpoint on closing the application, don't know if you have passed the parameters to put this A instance into the widget hierarchy so it gets closed.



  • @JonB said in I closed a dialog, but it seems to be still running:

    @MasterBlade
    It sounds like your int gid; is what you say, a global variable, not a member of your A class. So it has nothing to do with your class instances, and so will retain its value.

    Closing/re-opening a QWidget is not the same thing as new/delete-ing it, so it would not reset a member variable anyway. Unless you set Qt::WA_DeleteOnClose.

    Don't know about your breakpoint on closing the application, don't know if you have passed the parameters to put this A instance into the widget hierarchy so it gets closed.

    This is where breakpoint is.

    A::~A()
    {
        delete ui; //Breakpoint
    }
    

    I created an instance on a parent window. The main window.

    A* a = new A;
            a->show();
    

    Is this why a isn't destroyed after closing the window?


  • Lifetime Qt Champion

    @MasterBlade said in I closed a dialog, but it seems to be still running:

    Is this why a isn't destroyed after closing the window?

    Yes, because you don't delete it



  • @MasterBlade said in I closed a dialog, but it seems to be still running:

    I created an instance on a parent window. The main window.
    A* a = new A;
    a->show();

    No you didn't. There is no mention of the parent/main window here. In fact, given your code showing constructor A::A(QWidget* parent) I don't even know whether you have declared parent as optional/defaulting to nullptr like QWidget does. Assuming it does default (else your call wouldn't compile), you have not set its parent to the main window, it's a top-level window/modeless dialog and it won't get destroyed unless you do it explicitly.



  • @JonB said in I closed a dialog, but it seems to be still running:

    @MasterBlade said in I closed a dialog, but it seems to be still running:

    I created an instance on a parent window. The main window.
    A* a = new A;
    a->show();

    No you didn't. There is no mention of the parent/main window here. In fact, given your code showing constructor A::A(QWidget* parent) I don't even know whether you have declared parent as optional/defaulting to nullptr like QWidget does. Assuming it does default (else your call wouldn't compile), you have not set its parent to the main window, it's a top-level window/modeless dialog and it won't get destroyed unless you do it explicitly.

    Thank you. I thought closing the window would destroy it but it seems not.
    So how do I destroy it?



  • @MasterBlade
    Either by calling deleteLater() on it after you/the user has closed it, or by setting Qt::WA_DeleteOnClose on it, e.g.

    QDialog *dlg = new QDialog;
    dlg->setAttribute(Qt::WA_DeleteOnClose, true);    // either this line...
    dlg->exec();
    dlg->deleteLater();    // ...or this line
    

    If you give a QObject, such as a QWidget, a parent then it will get deleted if/when the parent gets deleted. This works well for non-top-level objects. But in your case you did not do that: you went new A. You said "I created an instance on a parent window.", but you didn't pass the parent, new A(parent), so it didn't have a parent and hence would not get destroyed with the parent.

    One tip is that there is a QObject::destroyed signal on every QObject. If you slot onto it and you don't see it being called, the object hasn't been destroyed!



  • @JonB said in I closed a dialog, but it seems to be still running:

    @MasterBlade
    Either by calling deleteLater() on it after you/the user has closed it, or by setting Qt::WA_DeleteOnClose on it, e.g.

    QDialog *dlg = new QDialog;
    dlg->setAttribute(Qt::WA_DeleteOnClose, true);    // either this line...
    dlg->exec();
    dlg->deleteLater();    // ...or this line
    

    If you give a QObject, such as a QWidget, a parent then it will get deleted if/when the parent gets deleted. This works well for non-top-level objects. But in your case you did not do that: you went new A. You said "I created an instance on a parent window.", but you didn't pass the parent, new A(parent), so it didn't have a parent and hence would not get destroyed with the parent.

    One tip is that there is a QObject::destroyed signal on every QObject. If you slot onto it and you don't see it being called, the object hasn't been destroyed!

    So I need to change it to

    A* a = new A(this);
    

    a gets destroyed when the mainwindow is closed.

    But I want to destroy a as soon as a's window is closed. How can I do that?
    Shall it be like

    A* a = new A(a);
    


  • @MasterBlade

    A* a = new A(a);
    

    Fortunately the compiler should stop you trying that. Please think about it: you can't make a's parent be a, not to mention that a is uninitialized when you pass it.

    But I want to destroy a as soon as a's window is closed. How can I do that?

    You saw that my code offered you a couple of ways, including:

    dlg->setAttribute(Qt::WA_DeleteOnClose, true); // either this line...

    That looks like a suitably named flag, doesn't it? https://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum



  • @JonB said in I closed a dialog, but it seems to be still running:

    @MasterBlade

    A* a = new A(a);
    

    Fortunately the compiler should stop you trying that. Please think about it: you can't make a's parent be a, not to mention that a is uninitialized when you pass it.

    But I want to destroy a as soon as a's window is closed. How can I do that?

    You saw that my code offered you a couple of ways, including:

    dlg->setAttribute(Qt::WA_DeleteOnClose, true); // either this line...

    That looks like a suitably named flag, doesn't it? https://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum

    Thank you so much! This problem is solved!

    Would you be kind to take a look at another problem I have? Looks like a compiler problem.
    https://forum.qt.io/topic/114057/watchlist-disappeared-during-debugging



  • @MasterBlade
    I did see that one and have no idea. It doesn't look right that it should do that! Does it happen elsewhere/on another program? Re-install Qt Creator? ;-)



  • @JonB said in I closed a dialog, but it seems to be still running:

    @MasterBlade
    I did see that one and have no idea. It doesn't look right that it should do that! Does it happen elsewhere/on another program? Re-install Qt Creator? ;-)

    This problem appeared recently. I don't know if it's a problem of qt or some software settings.

    During my test, only some functions are affected, and not always.
    For some functions, watchlist disappeared the first time I press F10, but it comes back later after a switch statement. Maybe I should reinstall QtCreator.


Log in to reply