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. Qt emit signal after widget is closed
Forum Updated to NodeBB v4.3 + New Features

Qt emit signal after widget is closed

Scheduled Pinned Locked Moved Solved General and Desktop
22 Posts 5 Posters 4.1k 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.
  • P pmanc

    Hi, I'll try to be more clear.
    I have a QMainWindow. From this, I open a QDialog. From the QDialog i press a QPushButton. When I press the button this occurs:

    QtConcurrent::run([=](QString ip) {
            QTcpSocket t;
            connect(this, SIGNAL(errorTcpSignal(QString)), this->parent(), SLOT(displayTcpError(QString)),Qt::QueuedConnection);
            connect(&t, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),[=](QAbstractSocket::SocketError err){
                emit errorTcpSignal("Error while changing game settings \n" + QVariant::fromValue(err).toString());
            });
            t.connectToHost(ip,8888);
            t.waitForConnected();
            if(t.state() == QAbstractSocket::ConnectedState)
            {
                t.write(s.toUtf8());
                t.waitForBytesWritten();
            }
            t.close();
    
        },Settings::ipPc);
    

    In the QMainWindow I have this slot:

    
    void MainWindow::displayTcpError(QString e)
    {
        GenericErrorDialog d("Error","An error occurred.\n"
                                     "\nThe complete error is:\n" + QVariant::fromValue(e).toString());
        d.exec();
    }
    

    GenericErrorDialog is a QDialog.
    The problem is:
    if there's an error with the socket the GenericErrorDialog appears if the user does not close the QDialog, but if the user closes the QDialog (without waiting for the socket to return the error) to return to QMainWindow, the error box is not shown.
    Thank you very much.

    jsulmJ Offline
    jsulmJ Offline
    jsulm
    Lifetime Qt Champion
    wrote on last edited by
    #4

    @pmanc said in Qt emit signal after widget is closed:

    connect(this, SIGNAL(errorTcpSignal(QString)), this->parent(), SLOT(displayTcpError(QString)),Qt::QueuedConnection);

    This should be other way around: the caller should connect the signals/slots. So, your dialog should have an error signal which you connect in MainWindow to displayTcpError. Children should not know anything about parents and especially they should not know implementation details of their parents (like displayTcpError()).

    https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    2
    • P Offline
      P Offline
      pmanc
      wrote on last edited by
      #5

      Thank you very much, you are right.
      The only problem is that :

      AdvancedDialog ad = new AdvancedDialog(this);
      connect(ad, SIGNAL(errorTcpSignal(QString)), this, SLOT(displayTcpError(QString)));
      ad->exec();
      ad->deleteLater();
      

      The deleteLater will make the program crash, if not included I'll have a memory leak.
      Anyway, I declared

      AdvancedDialog  ad
      

      in the header and in the QMainWindow constructor

      connect(&ad, SIGNAL(errorTcpSignal(QString)), this, SLOT(displayTcpError(QString)));
      

      This works, but is there a better way to do it?
      Cheers.

      jsulmJ 1 Reply Last reply
      0
      • P pmanc

        Thank you very much, you are right.
        The only problem is that :

        AdvancedDialog ad = new AdvancedDialog(this);
        connect(ad, SIGNAL(errorTcpSignal(QString)), this, SLOT(displayTcpError(QString)));
        ad->exec();
        ad->deleteLater();
        

        The deleteLater will make the program crash, if not included I'll have a memory leak.
        Anyway, I declared

        AdvancedDialog  ad
        

        in the header and in the QMainWindow constructor

        connect(&ad, SIGNAL(errorTcpSignal(QString)), this, SLOT(displayTcpError(QString)));
        

        This works, but is there a better way to do it?
        Cheers.

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #6

        @pmanc said in Qt emit signal after widget is closed:

        The deleteLater will make the program crash

        Did you analyse the crash? What happens? What are you doing in the destructor?

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • P Offline
          P Offline
          pmanc
          wrote on last edited by pmanc
          #7

          In the destuctor of AdvancedDialog there's only

          delete ui;
          

          The error is:

          Exception triggered
          the inferior stopped because it triggered an exception.
          Stopped in thread 18 by: Exception at 0x7fff5b5fd49 code 0xc0000005
          read access violation at 0xffffffffffffff  flags=0x0 (first chance)
          

          The debugger is stuck at

          AdvancedDialog::errorTcpSignal
          

          Thanks!

          Edit: I think the problem is that errorTcpSignal is declared in the header of AdvancedDialog, so when AdvancedDialog is deleted the signal cannot be emitted.

          1 Reply Last reply
          0
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #8

            We need to see the backtrace.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            1
            • P Offline
              P Offline
              pmanc
              wrote on last edited by
              #9

              I hope this is good

              upload.PNG

              Thanks!

              jsulmJ 1 Reply Last reply
              0
              • P pmanc

                I hope this is good

                upload.PNG

                Thanks!

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #10

                @pmanc Looks like the signal is still emitted. Can you try to disconnect manually before calling deleteLater() to see whether it still crashes?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                P 1 Reply Last reply
                0
                • jsulmJ jsulm

                  @pmanc Looks like the signal is still emitted. Can you try to disconnect manually before calling deleteLater() to see whether it still crashes?

                  P Offline
                  P Offline
                  pmanc
                  wrote on last edited by
                  #11

                  @jsulm I added

                  disconnect(ad, nullptr, nullptr, nullptr);
                  

                  before deleteLater, but still crashes, plus at live 295 I have a semantic error:

                  moc_advanceddialog.cpp:295:5: error: no matching function for call to 'activate'
                  qobjectdefs.h:397:17: note: candidate function not viable: no known conversion from 'AdvancedDialog *' to 'QObject *' for 1st argument
                  qobjectdefs.h:398:17: note: candidate function not viable: no known conversion from 'AdvancedDialog *' to 'QObject *' for 1st argument
                  qobjectdefs.h:396:17: note: candidate function not viable: requires 3 arguments, but 4 were provided
                  
                  J.HilkJ 1 Reply Last reply
                  0
                  • P pmanc

                    @jsulm I added

                    disconnect(ad, nullptr, nullptr, nullptr);
                    

                    before deleteLater, but still crashes, plus at live 295 I have a semantic error:

                    moc_advanceddialog.cpp:295:5: error: no matching function for call to 'activate'
                    qobjectdefs.h:397:17: note: candidate function not viable: no known conversion from 'AdvancedDialog *' to 'QObject *' for 1st argument
                    qobjectdefs.h:398:17: note: candidate function not viable: no known conversion from 'AdvancedDialog *' to 'QObject *' for 1st argument
                    qobjectdefs.h:396:17: note: candidate function not viable: requires 3 arguments, but 4 were provided
                    
                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #12

                    @pmanc QObject::Connect returns a QMetaObject::Connection you're supposed to store that and call disconnect on that object


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    P 1 Reply Last reply
                    0
                    • J.HilkJ J.Hilk

                      @pmanc QObject::Connect returns a QMetaObject::Connection you're supposed to store that and call disconnect on that object

                      P Offline
                      P Offline
                      pmanc
                      wrote on last edited by pmanc
                      #13

                      @J-Hilk
                      Sorry, i didn't know.
                      Now I have

                      AdvancedDialog *ad = new AdvancedDialog(this);
                      QMetaObject::Connection c = connect(ad, SIGNAL(errorTcpSignal(QString)), this, SLOT(displayTcpError(QString)));
                      ad->exec();
                      disconnect(c);
                      ad->deleteLater();
                      

                      But still crashes, this SIGNAL is emitted.

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

                        disconnect won't stop the signal emitting, just stop calling the slot.
                        I think you should disconnect the other connection, from that SocketError.
                        That connection doesn't have a receiver context, so the lambda will be called even after this is destroyed.
                        How about add this as the receiver context:

                        connect(&t, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), this, [=](QAbstractSocket::SocketError err){
                                    emit errorTcpSignal(...);
                                });
                        
                        P 1 Reply Last reply
                        1
                        • B Bonnie

                          disconnect won't stop the signal emitting, just stop calling the slot.
                          I think you should disconnect the other connection, from that SocketError.
                          That connection doesn't have a receiver context, so the lambda will be called even after this is destroyed.
                          How about add this as the receiver context:

                          connect(&t, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), this, [=](QAbstractSocket::SocketError err){
                                      emit errorTcpSignal(...);
                                  });
                          
                          P Offline
                          P Offline
                          pmanc
                          wrote on last edited by
                          #15

                          @Bonnie
                          Thank you very much for your reply.
                          The problem is that I want the signal to be emitted when I close the QDialog too.
                          I have MainWindow with the slot for the error, and the QDialog that emits the signal.
                          The core of the problem is that I want to receive the signal from QDialog 's QtConcurrent thread also after QDialog has been closed.

                          1 Reply Last reply
                          0
                          • B Offline
                            B Offline
                            Bonnie
                            wrote on last edited by Bonnie
                            #16

                            From your screen capture, the errorTcpSignal is a member from AdvancedDialog, right?
                            Where do you emit it then? I'm not quite understanding your code since I don't know what is this in those connections.
                            If you want the dialog to emit the signal, then you can't delete it.

                            P 1 Reply Last reply
                            0
                            • B Bonnie

                              From your screen capture, the errorTcpSignal is a member from AdvancedDialog, right?
                              Where do you emit it then? I'm not quite understanding your code since I don't know what is this in those connections.
                              If you want the dialog to emit the signal, then you can't delete it.

                              P Offline
                              P Offline
                              pmanc
                              wrote on last edited by
                              #17

                              @Bonnie
                              Yes, errorTcpSignal is a member from AdvancedDialog.
                              I emit it from a QtConcurrent thread in AdvancedDialog when an AdvancedDialog 's button is pressed.
                              If I don't delete it everything works, but I'll have a memory leak.

                              B 1 Reply Last reply
                              0
                              • P pmanc

                                @Bonnie
                                Yes, errorTcpSignal is a member from AdvancedDialog.
                                I emit it from a QtConcurrent thread in AdvancedDialog when an AdvancedDialog 's button is pressed.
                                If I don't delete it everything works, but I'll have a memory leak.

                                B Offline
                                B Offline
                                Bonnie
                                wrote on last edited by Bonnie
                                #18

                                @pmanc said in Qt emit signal after widget is closed:

                                If I don't delete it everything works, but I'll have a memory leak.

                                No, you won't.
                                It have a parent widget (in your code when you new it), so it will be deleted after the parent is destoyed.
                                But I still don't think it is a right design since you want to delete the dialog but also need it to send signals.
                                Though I don't fully understand your logic, I think you should handle the QtConcurrent related code in your QMainWindow.

                                P 1 Reply Last reply
                                0
                                • B Bonnie

                                  @pmanc said in Qt emit signal after widget is closed:

                                  If I don't delete it everything works, but I'll have a memory leak.

                                  No, you won't.
                                  It have a parent widget (in your code when you new it), so it will be deleted after the parent is destoyed.
                                  But I still don't think it is a right design since you want to delete the dialog but also need it to send signals.
                                  Though I don't fully understand your logic, I think you should handle the QtConcurrent related code in your QMainWindow.

                                  P Offline
                                  P Offline
                                  pmanc
                                  wrote on last edited by
                                  #19

                                  @Bonnie
                                  I see. But every time I open a new AdvancedDialog I see my memory use to grow in the task manager.
                                  Should I initialize AdvancedDialog once in the MainWindow constructor and show / hide it when I need?

                                  By the way, great community, everyone!

                                  jsulmJ B 2 Replies Last reply
                                  0
                                  • P pmanc

                                    @Bonnie
                                    I see. But every time I open a new AdvancedDialog I see my memory use to grow in the task manager.
                                    Should I initialize AdvancedDialog once in the MainWindow constructor and show / hide it when I need?

                                    By the way, great community, everyone!

                                    jsulmJ Offline
                                    jsulmJ Offline
                                    jsulm
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #20

                                    @pmanc said in Qt emit signal after widget is closed:

                                    But every time I open a new AdvancedDialog

                                    If you need this dialog often then don't delete it and don't recreate it each time you need it. Create it once.

                                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                                    1 Reply Last reply
                                    3
                                    • P pmanc

                                      @Bonnie
                                      I see. But every time I open a new AdvancedDialog I see my memory use to grow in the task manager.
                                      Should I initialize AdvancedDialog once in the MainWindow constructor and show / hide it when I need?

                                      By the way, great community, everyone!

                                      B Offline
                                      B Offline
                                      Bonnie
                                      wrote on last edited by
                                      #21

                                      @pmanc said in Qt emit signal after widget is closed:

                                      Should I initialize AdvancedDialog once in the MainWindow constructor and show / hide it when I need?

                                      If you want to keep handling QtConcurrent related things in the dialog , I think you should.

                                      P 1 Reply Last reply
                                      3
                                      • B Bonnie

                                        @pmanc said in Qt emit signal after widget is closed:

                                        Should I initialize AdvancedDialog once in the MainWindow constructor and show / hide it when I need?

                                        If you want to keep handling QtConcurrent related things in the dialog , I think you should.

                                        P Offline
                                        P Offline
                                        pmanc
                                        wrote on last edited by
                                        #22

                                        Ok thank you very much for your time!

                                        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