Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Closing a QDialog from another class

Closing a QDialog from another class

Scheduled Pinned Locked Moved General and Desktop
14 Posts 5 Posters 7.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    QMatt
    wrote on last edited by
    #1

    Hello everyone, I'm developing a desktop application in Qt 4.7.4 using QtCreator (Window 7, 64 bit).
    I'm trying to implement a sort of front controller to centralize the requests derived from the windows, so I created a class called frontcontroller, with frontcontroller.h and frontcontroller.cpp files.

    Everything seems to work, but... I have a QDialog window, created with QtCreator, that i want to open and close through frontcontroller.

    So, this is the frontcontroller class code:

    frontcontroller.h
    @
    #ifndef FRONTCONTROLLER_H
    #define FRONTCONTROLLER_H

    #include <QPointer>

    #include "win1.h"
    #include "win2.h"

    class Frontcontroller
    {
    public:
    Frontcontroller();
    //Application
    void StartApplication();

        //Windows
        void openWIN1();
        void closeWIN1();
    
    private:
        QPointer<W1> MW;
        QPointer<W2> secondW;
    

    };

    #endif // FRONTCONTROLLER_H
    @

    frontcontroller.cpp
    @
    #include <QMessageBox>

    #include "frontcontroller.h"

    Frontcontroller :: Frontcontroller()
    {

    }

    void Frontcontroller :: StartApplication()
    {
    MW = new WIN1();
    MW->showMaximized();
    }

    void Frontcontroller :: openInsertArticleWin()
    {
    seconW = new W2(); //This is a QDialog
    seconW->setAttribute( Qt::WA_DeleteOnClose, true );
    seconW->exec();
    }

    void Frontcontroller :: closeInsertArticleWin()
    {
    seconW->close();
    }

    void Frontcontroller :: resetDataForInsertArticle()
    {
    //TODO
    }
    @

    My problem: when i close the QDialog (secondW, excuse me for var names) through the FC, the whole program crashes exiting with code -1073741819 (Access Violation, right?) and I can not understand what is wrong.
    Can someone help me?
    Thanks a lot, bye bye

    1 Reply Last reply
    0
    • F Offline
      F Offline
      franku
      wrote on last edited by
      #2

      You must not access GUI elements from threads other than the GUI thread. So the first thread will live in this loop:

      @
      void Frontcontroller :: openInsertArticleWin()
      {
      seconW = new W2(); //This is a QDialog
      seconW->setAttribute( Qt::WA_DeleteOnClose, true );
      seconW->exec(); <---- here
      }
      @

      and the second thread will close the window with

      @
      void Frontcontroller :: closeInsertArticleWin()
      {
      seconW->close();
      }
      @

      right?

      This, Jen, is the internet.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        franku
        wrote on last edited by
        #3

        You can use QThread:currentThreadId() to qDebug() the current thread ID in each class method to figure out what thread is currently running.

        Simply add:

        @
        #include <QDebug>
        ...
        qDebug() << currentThreadId();
        ...
        @

        and see if the output was same or not, then proceed with other questions.

        This, Jen, is the internet.

        1 Reply Last reply
        0
        • Q Offline
          Q Offline
          QMatt
          wrote on last edited by
          #4

          [quote author="franku" date="1345213377"]You must not access GUI elements from threads other than the GUI thread. So the first thread will live in this loop:

          @
          void Frontcontroller :: openInsertArticleWin()
          {
          seconW = new W2(); //This is a QDialog
          seconW->setAttribute( Qt::WA_DeleteOnClose, true );
          seconW->exec(); <---- here
          }
          @

          and the second thread will close the window with

          @
          void Frontcontroller :: closeInsertArticleWin()
          {
          seconW->close();
          }
          @

          right?
          [/quote]

          Thnaks for your reply franku, I don't fully understand your answer when you say: "You must not access GUI elements from threads other than the GUI thread"... I have tried the show() instrucrtion instad of exec(), but it is the same.
          So i tried you suggestion, and the thread seems to be the same, here is the output
          @
          A moment before running exec();
          0x14c8
          When i try to close the window via FC
          0x14c8
          @

          So I have tried to debug the secondW variable, and...
          @
          A moment before
          secondW(0x7b16e8, name = "secondW")
          When closing via FC
          QObject(0x0)
          @

          I have to think that the pointer "secondW" is not instantiated when i close the QDialog?

          1 Reply Last reply
          0
          • F Offline
            F Offline
            franku
            wrote on last edited by
            #5

            Hi, sorry. I mean:

            @
            void Frontcontroller :: openInsertArticleWin()
            {
            qDebug() << "Exec-Thread" << QThread::currentThreadId();

                seconW = new W2();  //This is a QDialog
                seconW->setAttribute( Qt::WA_DeleteOnClose, true );
                seconW->exec&#40;&#41;; 
            }
            

            @

            and

            @
            void Frontcontroller :: closeInsertArticleWin()
            {
            qDebug() << "Close-Thread" << QThread::currentThreadId();

                seconW->close();
            }
            

            @

            Exec-Thread and Close-Thread must not be different. If they are, you have to use some event-queue to do it. If you figure out the IDs, we can try to find a solution.

            This, Jen, is the internet.

            1 Reply Last reply
            0
            • Q Offline
              Q Offline
              QMatt
              wrote on last edited by
              #6

              Thank you again franku.
              Here is the debug output:

              @
              Exec-Thread: 0xc60
              Close-Thread 0xc60
              @

              So the open and close threads seems to be the same

              1 Reply Last reply
              0
              • M Offline
                M Offline
                mlong
                wrote on last edited by
                #7

                franku: I'm not sure how threads enter the picture. I'm not sure that this is a multithreaded situation at all... the exec() call was a QDialog::exec(), not a QThread::exec(), as I understand it.

                Software Engineer
                My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mlong
                  wrote on last edited by
                  #8

                  Is the dialog modal? (I assume so, since you're using exec() to open it, instead of show().) If so, have you tried calling accept() or reject() instead of close() to close it? I'm not sure off the top of my head how calling close() on a running modal dialog works, as there may be pending events in its event loop, etc. Also, if there's a DeleteOnClose situation, are you sure that the variable isn't still being referenced somewhere else?

                  Can you get a working backtrace from the debugger when it crashes?

                  Software Engineer
                  My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                  1 Reply Last reply
                  0
                  • Q Offline
                    Q Offline
                    QMatt
                    wrote on last edited by
                    #9

                    Hi mlong, no, the Dialog is not modal, but i have tried to it to modal and call show() instead of exec(), I have tried to call show() without setModal(), nothing change.
                    Yes, I have tried to call accept() and reject instead of close() (my first attempt, actually), nothing and nothing.
                    What seems suspicious is that when closing the Dialog, debugging of the poniter returns a QObject (0x0)

                    1 Reply Last reply
                    0
                    • W Offline
                      W Offline
                      webmaster.skelton
                      wrote on last edited by
                      #10

                      If it is returning a QObject(0x0) you are get a Null pointer exception. Somewhere along the way it is losing reference to your pointer, though from the code you have given I would not be sure where at.

                      1 Reply Last reply
                      0
                      • F Offline
                        F Offline
                        franku
                        wrote on last edited by
                        #11

                        bq. I’m not sure how threads enter the picture.

                        Well, some thread must execute the exec() method of the Dialog. In most cases I think this is done by the thread that runs the gui. But I did not know if QMatt uses another thread than the guithread to close() the window. So I wanted to be sure before we think about other possibilities.

                        bq. ...if there’s a DeleteOnClose situation, ...

                        In that case you could use dialog->setAttribute(Qt::WA_DeleteOnClose, false) to improve that the object isnt't deleted after finishing the event loop. Afterwards you have to delete it manually (for a quick test just don't delete it).

                        But as mlogn and webmaster. mentioned above, what does the debugger say?

                        QMatt, did you run the code step by step to see what is going on? You may want to create some breakpoints in each method and see what happens, especially when the object is deleted.

                        This, Jen, is the internet.

                        1 Reply Last reply
                        0
                        • Q Offline
                          Q Offline
                          QMatt
                          wrote on last edited by
                          #12

                          Hi guys and thanks a lot for your patience with me...
                          Trying to start debugging (Debug -> Start Debugging), I receive this message:
                          @
                          The inferior stopped because it received a signal from the Operating System.
                          Signal name: SIGSEGV
                          Signal meaning: Segmentation fault
                          @

                          And a disassembler appears with an ASM code with a right arrow @ line n. 8
                          How (and if) I can print a Stack Trace or someting similar?

                          1 Reply Last reply
                          0
                          • Q Offline
                            Q Offline
                            QMatt
                            wrote on last edited by
                            #13

                            Ok so... probably the night brings counsel, or maybe I am stupid...
                            When I call exec() on secondW, I need to use the Frontcontroller in this window, so I do
                            @
                            Frontconrtoller fc;
                            ...
                            ...
                            ...
                            void insertArticleWin :: on_cancelButton_clicked() { fc.closeWIN2(); }
                            @

                            but this is a new instance of Frontcontroller, a different object, right? So the pointer to secondW is set to NULL... and so I just made this change

                            @
                            Frontconrtoller fc;
                            ...
                            ...
                            ...
                            void insertArticleWin :: on_cancelButton_clicked() { fc.secondW = this; fc.closeInsertArticleWin(); }
                            @

                            And now all seems to work... do you think what I am doing is theoretically wrong?

                            1 Reply Last reply
                            0
                            • B Offline
                              B Offline
                              blobfish
                              wrote on last edited by
                              #14

                              You are creating modal dialog and trying to use it like a modeless one. exec blocks until the dialog is closed and then returns. So in a true modal environment, your closeInsertArticleWin() function couldn't be called until after the dialog is closed. It sounds like to me that you should be working with a modeless dialog (QDialog::show) instead of QDialog::exec and set your qobject parenting. I don't think you want deleteOnClose. Modeless dialog should be constructed upon app start shown and hidden by controller and deleted on app shutdown.

                              you should check seconW before using it. That is what qpointer is for. i.e. @if (seconW)
                              seconW->close();@

                              If you can, post something we can easily build.

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved