Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QProcess freezes UI
Forum Updated to NodeBB v4.3 + New Features

QProcess freezes UI

Scheduled Pinned Locked Moved Solved Mobile and Embedded
13 Posts 4 Posters 1.8k Views 1 Watching
  • 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.
  • I Offline
    I Offline
    Iheb
    wrote on last edited by Iheb
    #1

    Hello,

    I'm using a QProcess to run system commands but it freezes the UI while using waitForFinished which is normal as its indicated in the documentation. I tried to use signals and slots but it still freezes. Here is my code:

    bool NetworkConnection::connectEthernetDynamic(){
    
     
        QProcess con_process = new QProcess;
        
        con_process->start("nmcli con add type ethernet con-name my_connection ifname eth0");
        connect(con_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                [this, con_process](int exitCode, QProcess::ExitStatus exitStatus){
            QString output2(con_process->readAllStandardOutput());
            if (output2.contains("successfully")){
                QProcess process;
                process.start("nmcli con up my_connection");
                process.waitForFinished();
                QString output3(process.readAllStandardOutput());
                return output3.contains("successfully");
            }
        });
    }
    
    
    JonBJ 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Signals and slots does not mean that the slot is executed in a different thread. The only time it is the case is when the target thread affinity is a different thread than the one where the signal is originating.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      I 1 Reply Last reply
      1
      • I Iheb

        Hello,

        I'm using a QProcess to run system commands but it freezes the UI while using waitForFinished which is normal as its indicated in the documentation. I tried to use signals and slots but it still freezes. Here is my code:

        bool NetworkConnection::connectEthernetDynamic(){
        
         
            QProcess con_process = new QProcess;
            
            con_process->start("nmcli con add type ethernet con-name my_connection ifname eth0");
            connect(con_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                    [this, con_process](int exitCode, QProcess::ExitStatus exitStatus){
                QString output2(con_process->readAllStandardOutput());
                if (output2.contains("successfully")){
                    QProcess process;
                    process.start("nmcli con up my_connection");
                    process.waitForFinished();
                    QString output3(process.readAllStandardOutput());
                    return output3.contains("successfully");
                }
            });
        }
        
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #3

        @Iheb
        What can we say other than: your outer QProcess does not use waitForFinished(), so it does not block. But if you get successfully back, you then create another QProcess which does call waitForFinished(). Hence that blocks.

        I tried to use signals and slots but it still freezes.

        Show what you did, because signals & slots will not block/freeze. One way would be: if you make your inner process do a signal on QProcess::finished just like you outer one does, that would be a starting approach.

        I 1 Reply Last reply
        2
        • SGaistS SGaist

          Hi,

          Signals and slots does not mean that the slot is executed in a different thread. The only time it is the case is when the target thread affinity is a different thread than the one where the signal is originating.

          I Offline
          I Offline
          Iheb
          wrote on last edited by
          #4

          @SGaist Hi, so what should I do?

          JonBJ SGaistS 2 Replies Last reply
          0
          • I Iheb

            @SGaist Hi, so what should I do?

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #5

            @Iheb said in QProcess freezes UI:

            @SGaist Hi, so what should I do?

            @JonB said in QProcess freezes UI:

            One way would be: if you make your inner process do a signal on QProcess::finished just like you outer one does, that would be a starting approach.

            Did you choose to ignore this suggestion? Or do you only wish @SGaist to respond?

            I 1 Reply Last reply
            0
            • JonBJ JonB

              @Iheb
              What can we say other than: your outer QProcess does not use waitForFinished(), so it does not block. But if you get successfully back, you then create another QProcess which does call waitForFinished(). Hence that blocks.

              I tried to use signals and slots but it still freezes.

              Show what you did, because signals & slots will not block/freeze. One way would be: if you make your inner process do a signal on QProcess::finished just like you outer one does, that would be a starting approach.

              I Offline
              I Offline
              Iheb
              wrote on last edited by
              #6

              @JonB Yes I thought about that too and I tried something like this but it still freezes

              bool NetworkConnection::connectEthernetDynamic(){
                   auto con_process = new QProcess;
                   con_process->start("nmcli con add type ethernet con-name my_connection ifname eth0");
                   connect(con_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                               [this, con_process](int exitCode, QProcess::ExitStatus exitStatus){
                           QString output2(con_process->readAllStandardOutput());
                           if (output2.contains("successfully")){
                              auto process = new QProcess;
                              process->start("nmcli con up my_connection");
                              connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                                      [this, process](int exitCode, QProcess::ExitStatus exitStatus){
                                          QString output3(process->readAllStandardOutput());
                                          return output3.contains("successfully");
                              });
                          }
                      });
              }
              
              
              JonBJ 2 Replies Last reply
              0
              • I Iheb

                @JonB Yes I thought about that too and I tried something like this but it still freezes

                bool NetworkConnection::connectEthernetDynamic(){
                     auto con_process = new QProcess;
                     con_process->start("nmcli con add type ethernet con-name my_connection ifname eth0");
                     connect(con_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                                 [this, con_process](int exitCode, QProcess::ExitStatus exitStatus){
                             QString output2(con_process->readAllStandardOutput());
                             if (output2.contains("successfully")){
                                auto process = new QProcess;
                                process->start("nmcli con up my_connection");
                                connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                                        [this, process](int exitCode, QProcess::ExitStatus exitStatus){
                                            QString output3(process->readAllStandardOutput());
                                            return output3.contains("successfully");
                                });
                            }
                        });
                }
                
                
                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @Iheb
                Looking through, I would not expect this to "freeze", whatever else it might do. Put it some qDebug() statements, immediately before & after the start() lines and at each step in the slots. You/we need to understand what line you say it blocks/freezes on in the code you show.

                EDIT Oohh, I just noticed: you are connecting your slots after you have issued the start() statement. You must not do that, it may (well) be missed! connect() the signal/slot immediately after creating the QProcess instances, before you go start() on them.

                As a separate observation, once you have this working satisfactorily you will need to delete the two QProcesses you create which currently leak.

                1 Reply Last reply
                0
                • JonBJ JonB

                  @Iheb said in QProcess freezes UI:

                  @SGaist Hi, so what should I do?

                  @JonB said in QProcess freezes UI:

                  One way would be: if you make your inner process do a signal on QProcess::finished just like you outer one does, that would be a starting approach.

                  Did you choose to ignore this suggestion? Or do you only wish @SGaist to respond?

                  I Offline
                  I Offline
                  Iheb
                  wrote on last edited by
                  #8

                  @JonB I didn't choose to ignore your suggestion nor wishing only @SGaist to reply I simply just have about 10 min 1-reply interval (I don't have enough reputation to reply so I have to wait 10 min between each one)

                  JonBJ 1 Reply Last reply
                  0
                  • I Iheb

                    @JonB I didn't choose to ignore your suggestion nor wishing only @SGaist to reply I simply just have about 10 min 1-reply interval (I don't have enough reputation to reply so I have to wait 10 min between each one)

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #9

                    @Iheb said in QProcess freezes UI:

                    @JonB I didn't choose to ignore your suggestion nor wishing only @SGaist to reply I simply just have about 10 min 1-reply interval (I don't have enough reputation to reply so I have to wait 10 min between each one)

                    Not a problem :) Read my latest response above, including the need to change the order of your statements, and let us know.

                    1 Reply Last reply
                    0
                    • I Iheb

                      @JonB Yes I thought about that too and I tried something like this but it still freezes

                      bool NetworkConnection::connectEthernetDynamic(){
                           auto con_process = new QProcess;
                           con_process->start("nmcli con add type ethernet con-name my_connection ifname eth0");
                           connect(con_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                                       [this, con_process](int exitCode, QProcess::ExitStatus exitStatus){
                                   QString output2(con_process->readAllStandardOutput());
                                   if (output2.contains("successfully")){
                                      auto process = new QProcess;
                                      process->start("nmcli con up my_connection");
                                      connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                                              [this, process](int exitCode, QProcess::ExitStatus exitStatus){
                                                  QString output3(process->readAllStandardOutput());
                                                  return output3.contains("successfully");
                                      });
                                  }
                              });
                      }
                      
                      
                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #10

                      @Iheb
                      And a further observation, which might affect how you are (trying to) use this code.

                      The return output3.contains("successfully") statement only returns a result for the slot connected to the second QProcess --- which is thrown away, as nobody cares about it.

                      Meanwhile you have bool NetworkConnection::connectEthernetDynamic(), which at present is not returning any result itself. I am surprised you do not get a compiler warning for this? You must arrange your code differently, your connectEthernetDynamic() is non-blocking (as you desire) so it cannot return a value about the completion of the processes. Instead it will return immediately. So if you need to use the second process's output result, you will need to change how you do that. But you should be able to get the processes running without freeze initially if you skip needing the result.

                      I 1 Reply Last reply
                      2
                      • I Iheb

                        @SGaist Hi, so what should I do?

                        SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @Iheb said in QProcess freezes UI:

                        @SGaist Hi, so what should I do?

                        As @JonB suggests, rethink your design to properly take advantage of the asynchronous nature of Qt.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0
                        • JonBJ JonB

                          @Iheb
                          And a further observation, which might affect how you are (trying to) use this code.

                          The return output3.contains("successfully") statement only returns a result for the slot connected to the second QProcess --- which is thrown away, as nobody cares about it.

                          Meanwhile you have bool NetworkConnection::connectEthernetDynamic(), which at present is not returning any result itself. I am surprised you do not get a compiler warning for this? You must arrange your code differently, your connectEthernetDynamic() is non-blocking (as you desire) so it cannot return a value about the completion of the processes. Instead it will return immediately. So if you need to use the second process's output result, you will need to change how you do that. But you should be able to get the processes running without freeze initially if you skip needing the result.

                          I Offline
                          I Offline
                          Iheb
                          wrote on last edited by
                          #12

                          @JonB Hi again, I confirm your suggestion works well. I found that I have another QProcess running just before the function and has waitforfinished. Using nested signal and slots for QProcess won't freeze the UI. I also managed to arrange my code to work as desired and the connectEthernetDynamic() became a void function.

                          J 1 Reply Last reply
                          3
                          • I Iheb

                            @JonB Hi again, I confirm your suggestion works well. I found that I have another QProcess running just before the function and has waitforfinished. Using nested signal and slots for QProcess won't freeze the UI. I also managed to arrange my code to work as desired and the connectEthernetDynamic() became a void function.

                            J Offline
                            J Offline
                            johnyboy
                            wrote on last edited by
                            #13

                            @Iheb Could you share your new working code please?

                            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