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. instantiating QMessageBox in a slot it doesn't respond
Forum Updated to NodeBB v4.3 + New Features

instantiating QMessageBox in a slot it doesn't respond

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 2 Posters 474 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.
  • B Offline
    B Offline
    Black Imp
    wrote on last edited by
    #1

    I have a QDialog managing connection and login to a server. When login response arrives on the socket I propagate the result calling a function of my custom dialog, here I send a signal which is connected to a slot of same dialog and here finally I handle the result and UI changes.
    Signal-slot are necessary because socket reading thread is not the same where UI is.
    It works correctly as far as I change dialog widgets, but if I create a message box in that slot it gets no focus nor it's possible to close it or even interact with it and the whole application UI.

    code for creating message box is simple:

    QMessageBox::warning(this , "Login Result", "Log In Attempt FAILED");

    "this " should be my custom dialog object.
    I've tested the same code in my dialog constructor and it works perfectly.
    So the problem is : how do I instantiate such a message box in a slot ?

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

      Please provide some code / an example. I would guess your threading is wrong and the QMessageBox is not called in the main thread.
      Why do you need to read data from a socket in a separate thread at all?

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

      B 1 Reply Last reply
      2
      • Christian EhrlicherC Christian Ehrlicher

        Please provide some code / an example. I would guess your threading is wrong and the QMessageBox is not called in the main thread.
        Why do you need to read data from a socket in a separate thread at all?

        B Offline
        B Offline
        Black Imp
        wrote on last edited by
        #3

        @Christian-Ehrlicher
        I was just supposing it does. It's not my thread...

        in the class holding socket I have a slot for reading from socket. I hold a listeners list , classes instances that registered themself to ClassWithSocket. Those classes must implement

        class ConnectionListener
        {
        public:
        virtual void onConnectionStatusChanged(ConnectionStatus status) = 0;
        virtual void onLogStatusChanged(LogStatus satus) = 0;
        virtual void onMessageSent(bool ok) = 0;
        };

        My conncetion dialog inherits from this.

        Class containing socket :

        ClassWithSocket::ClassWithSocket()
        {
        ...
        connect(mSocket, SIGNAL(readyRead()), this, SLOT(onDataReadyFromSocket()));
        ...
        }

        (this is a slot)
        ClassWithSocket::onDataReadyFromSocket()
        {
        readLoginResponse();
        }

        void ClassWithSocket::readLoginResponse()
        {
        ... listener->onLogStatusChanged(NotConnected);
        }

        my connection dialog is declared as follows:

        class ConnectionDialog : public QDialog, public ConnectionListener
        {
        Q_OBJECT
        public:
        ConnectionDialog();
        void onConnectionStatusChanged(ConnectionStatus status);
        void onLogStatusChanged(LogStatus status);
        void onMessageSent(bool ok) {}
        signals:
        void connectionStatusChanged(ConnectionStatus status);
        void logStatusChanged(LogStatus status);
        private slots:
        void connectionStatusChangedSlot(ConnectionStatus status);
        void logStatusChangedSlot(LogStatus status);
        ...
        }

        constructor:
        ConnectionDialog::ConnectionDialog()
        {

        connect(this, SIGNAL(connectionStatusChanged(ConnectionStatus)), this, SLOT(connectionStatusChangedSlot(ConnectionStatus)));
        connect(this, SIGNAL(logStatusChanged(LogStatus)), this, SLOT(logStatusChangedSlot(LogStatus)));
        }

        void ConnectionDialog::onConnectionStatusChanged(ConnectionStatus status)
        {
        emit connectionStatusChanged(status);
        }

        void ConnectionDialog::onLogStatusChanged(LogStatus status)
        {
        emit logStatusChanged(status);
        }

        void ConnectionDialog::logStatusChangedSlot(LogStatus status)
        {
        ...
        }

        so in a slot of ClassWithSocket i read response, i call a function of stored listener which is a QDialog, in this dialog i send a signal which is connected to a slot of the same class and here I try to instantiate the messagebox.

        1 Reply Last reply
        0
        • B Offline
          B Offline
          Black Imp
          wrote on last edited by
          #4

          I 've just tried a bypass:
          in

          void ConnectionDialog::onLogStatusChanged(LogStatus status) which is the function called by socket reading slot I dont' emit any signal and I modify directly my UI and create message box.

          void ConnectionDialog::onLogStatusChanged(LogStatus status)
          {
          //emit logStatusChanged(status);
          logStatusChangedSlot(status);
          }
          void ConnectionDialog::logStatusChangedSlot(LogStatus status)
          {
          QMessageBox::warning(this , "Login Result", "Log In Attempt FAILED"); // I've tried passing 0 as well instead of this as parent
          logStatus->setText("Login FAILED!");
          }

          same result. I cant interact with message box and it's all frozen

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

            I would use a QueuedConnection for such things because the way you do it now is to create a new QEventLoop within a socket operation which is maybe not that good.

            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
            4
            • B Offline
              B Offline
              Black Imp
              wrote on last edited by
              #6

              My bad. I thought qt would recognize automatically this kind of situation.

              NOW it works. THANK YOU!

              for those who may be interested:

              I had to add

              qRegisterMetaType<LogStatus>();

              to main.cpp function and modify signal slot connection like this:

              connect(this, SIGNAL(logStatusChanged(LogStatus)), this, SLOT(logStatusChangedSlot(LogStatus)), Qt::QueuedConnection);

              1 Reply Last reply
              2

              • Login

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