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. Problem with Connect and Lambda functions
Forum Update on Tuesday, May 27th 2025

Problem with Connect and Lambda functions

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 5 Posters 1.2k Views 4 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.
  • J Offline
    J Offline
    JonexElectronic
    wrote on 16 Jan 2023, 12:48 last edited by
    #1

    Hello. It is my first time using a lambda function in QObject::connect

    QProcess *process = new QProcess(this);
        QObject::connect(process, &QProcess::finished, this, [this, process](){
            int id = m_processes.key(process);
            emit processFinished(id);
        });
    

    It gives me some errors, and I dont know how to solve it
    88e75142-5cd1-4aa6-9669-29e4ce91f535-image.png

    Any idea? What I am doing wrong??

    J 1 Reply Last reply 16 Jan 2023, 17:23
    0
    • J JonexElectronic
      16 Jan 2023, 17:20

      @Chris-Kawa I am using Qt 5.15.2 and compiler mingw81_32

      C Offline
      C Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on 16 Jan 2023, 17:42 last edited by
      #10

      @JonexElectronic said:

      I am using Qt 5.15.2

      Oh, that makes sense. In Qt5 there are two overloads of QProcess::finished. They were merged in Qt 6. In Qt5 you have to explicitly choose one, so either

      connect(process, qOverload<int>(&QProcess::finished), this, [this, process](){
      

      or

      connect(process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, [this, process](){
      
      J 1 Reply Last reply 17 Jan 2023, 11:22
      3
      • A Offline
        A Offline
        Axel Spoerl
        Moderators
        wrote on 16 Jan 2023, 13:18 last edited by
        #2

        The error is in procesos.cpp. Very hard to guess, without clairvoyant abilities.
        Maybe you want to post all your code, including the header?

        Software Engineer
        The Qt Company, Oslo

        J 1 Reply Last reply 16 Jan 2023, 15:53
        0
        • C Offline
          C Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on 16 Jan 2023, 13:25 last edited by Chris Kawa
          #3

          Is ProcessController derived from QObject?

          J 1 Reply Last reply 16 Jan 2023, 15:47
          1
          • C Chris Kawa
            16 Jan 2023, 13:25

            Is ProcessController derived from QObject?

            J Offline
            J Offline
            JonexElectronic
            wrote on 16 Jan 2023, 15:47 last edited by
            #4

            @Chris-Kawa Yes it is

            1 Reply Last reply
            0
            • A Axel Spoerl
              16 Jan 2023, 13:18

              The error is in procesos.cpp. Very hard to guess, without clairvoyant abilities.
              Maybe you want to post all your code, including the header?

              J Offline
              J Offline
              JonexElectronic
              wrote on 16 Jan 2023, 15:53 last edited by JonexElectronic
              #5

              @Axel-Spoerl
              I am sure that the problem is in lambda functions because if I comment this line it compile perfect

              process.h

              class ProcessController : public QObject
              {
                  Q_OBJECT
              
              public:
                  explicit ProcessController(QObject *parent = nullptr);
                  ~ProcessController();
              
                  int addProcess(const QString &command, const QStringList &arguments);
                  void startProcess(int id);
                  void stopProcess(int id);
                  
              signals:
                  void processFinished(int id);
              
              private:
                  QMap<int, QProcess*> m_processes;
                  QMap<int, QString> m_command;
                  QMap<int, QStringList> m_arguments;
                  int m_nextId;
              };
              

              process.cpp

              ProcessController::ProcessController(QObject *parent) : QObject(parent)
              {
                  m_nextId = 0;
              }
              
              ProcessController::~ProcessController()
              {
                  for (auto process : m_processes) {
                      process->terminate();
                      process->waitForFinished();
                      delete process;
                  }
                  m_processes.clear();
                  m_command.clear();
                  m_arguments.clear();
              }
              
              int ProcessController::addProcess(const QString &command, const QStringList &arguments)
              {
                  QProcess *process = new QProcess(this);
                  connect(process, &QProcess::finished, this, [this, process](){
                      int id = m_processes.key(process);
                      emit processFinished(id);
                  });
                  int id = m_nextId++;
                  m_processes[id] = process;
                  m_command[id]= command;
                  m_arguments[id] = arguments;
                  return id;
              }
              
              void ProcessController::startProcess(int id)
              {
                  if(!m_processes.contains(id))
                      return;
                  QProcess *process = m_processes[id];
                  QString command = m_command[id];
                  QStringList arguments = m_arguments[id];
                  process->start(command, arguments);
              }
              
              void ProcessController::stopProcess(int id)
              {
                  if(!m_processes.contains(id))
                      return;
                  QProcess *process = m_processes[id];
                  process->terminate();
                  process->waitForFinished();
              }
              
              C 1 Reply Last reply 16 Jan 2023, 16:45
              0
              • fcarneyF Offline
                fcarneyF Offline
                fcarney
                wrote on 16 Jan 2023, 16:14 last edited by
                #6

                Change:

                connect(process, &QProcess::finished, this, [this, process](){
                        int id = m_processes.key(process);
                        emit processFinished(id);
                    });
                

                To :

                connect(process, &QProcess::finished, [this, process](){
                        int id = m_processes.key(process);
                        emit processFinished(id);
                    });
                

                You don't need to specify destination object in a functor connect.

                C++ is a perfectly valid school of magic.

                1 Reply Last reply
                1
                • J JonexElectronic
                  16 Jan 2023, 15:53

                  @Axel-Spoerl
                  I am sure that the problem is in lambda functions because if I comment this line it compile perfect

                  process.h

                  class ProcessController : public QObject
                  {
                      Q_OBJECT
                  
                  public:
                      explicit ProcessController(QObject *parent = nullptr);
                      ~ProcessController();
                  
                      int addProcess(const QString &command, const QStringList &arguments);
                      void startProcess(int id);
                      void stopProcess(int id);
                      
                  signals:
                      void processFinished(int id);
                  
                  private:
                      QMap<int, QProcess*> m_processes;
                      QMap<int, QString> m_command;
                      QMap<int, QStringList> m_arguments;
                      int m_nextId;
                  };
                  

                  process.cpp

                  ProcessController::ProcessController(QObject *parent) : QObject(parent)
                  {
                      m_nextId = 0;
                  }
                  
                  ProcessController::~ProcessController()
                  {
                      for (auto process : m_processes) {
                          process->terminate();
                          process->waitForFinished();
                          delete process;
                      }
                      m_processes.clear();
                      m_command.clear();
                      m_arguments.clear();
                  }
                  
                  int ProcessController::addProcess(const QString &command, const QStringList &arguments)
                  {
                      QProcess *process = new QProcess(this);
                      connect(process, &QProcess::finished, this, [this, process](){
                          int id = m_processes.key(process);
                          emit processFinished(id);
                      });
                      int id = m_nextId++;
                      m_processes[id] = process;
                      m_command[id]= command;
                      m_arguments[id] = arguments;
                      return id;
                  }
                  
                  void ProcessController::startProcess(int id)
                  {
                      if(!m_processes.contains(id))
                          return;
                      QProcess *process = m_processes[id];
                      QString command = m_command[id];
                      QStringList arguments = m_arguments[id];
                      process->start(command, arguments);
                  }
                  
                  void ProcessController::stopProcess(int id)
                  {
                      if(!m_processes.contains(id))
                          return;
                      QProcess *process = m_processes[id];
                      process->terminate();
                      process->waitForFinished();
                  }
                  
                  C Offline
                  C Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on 16 Jan 2023, 16:45 last edited by
                  #7

                  @JonexElectronic It looks ok and compiles fine for me. The error is about the old syntax connect, while you're using the new one. What Qt version and compiler do you get that error on? Which C++ version are you using?

                  @fcarney While not strictly necessary, it's always a good idea to pass the context object parameter. In this case we're within the same class, but in general if you use an object in the lambda and it dies before the connection does it's possible to invoke the lambda with a dead object. So passing the object as context is a good idea so the connection is severed when the object dies.

                  J 1 Reply Last reply 16 Jan 2023, 17:20
                  4
                  • C Chris Kawa
                    16 Jan 2023, 16:45

                    @JonexElectronic It looks ok and compiles fine for me. The error is about the old syntax connect, while you're using the new one. What Qt version and compiler do you get that error on? Which C++ version are you using?

                    @fcarney While not strictly necessary, it's always a good idea to pass the context object parameter. In this case we're within the same class, but in general if you use an object in the lambda and it dies before the connection does it's possible to invoke the lambda with a dead object. So passing the object as context is a good idea so the connection is severed when the object dies.

                    J Offline
                    J Offline
                    JonexElectronic
                    wrote on 16 Jan 2023, 17:20 last edited by
                    #8

                    @Chris-Kawa I am using Qt 5.15.2 and compiler mingw81_32

                    C 1 Reply Last reply 16 Jan 2023, 17:42
                    0
                    • J JonexElectronic
                      16 Jan 2023, 12:48

                      Hello. It is my first time using a lambda function in QObject::connect

                      QProcess *process = new QProcess(this);
                          QObject::connect(process, &QProcess::finished, this, [this, process](){
                              int id = m_processes.key(process);
                              emit processFinished(id);
                          });
                      

                      It gives me some errors, and I dont know how to solve it
                      88e75142-5cd1-4aa6-9669-29e4ce91f535-image.png

                      Any idea? What I am doing wrong??

                      J Offline
                      J Offline
                      JonB
                      wrote on 16 Jan 2023, 17:23 last edited by JonB
                      #9

                      @JonexElectronic
                      As @Chris-Kawa says, please confirm just which version of Qt you are using? E.g. Qt 4 would not be good! UPDATE OK, 5.15 is fine.

                      But also, just in case, delete the build output directory and recompile from scratch. Adding Q_OBJECT macro can cause a problem, though usually at link time. You have a compile error, but just in case make sure you have recompiled from absolute scratch....

                      1 Reply Last reply
                      1
                      • J JonexElectronic
                        16 Jan 2023, 17:20

                        @Chris-Kawa I am using Qt 5.15.2 and compiler mingw81_32

                        C Offline
                        C Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on 16 Jan 2023, 17:42 last edited by
                        #10

                        @JonexElectronic said:

                        I am using Qt 5.15.2

                        Oh, that makes sense. In Qt5 there are two overloads of QProcess::finished. They were merged in Qt 6. In Qt5 you have to explicitly choose one, so either

                        connect(process, qOverload<int>(&QProcess::finished), this, [this, process](){
                        

                        or

                        connect(process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, [this, process](){
                        
                        J 1 Reply Last reply 17 Jan 2023, 11:22
                        3
                        • C Chris Kawa
                          16 Jan 2023, 17:42

                          @JonexElectronic said:

                          I am using Qt 5.15.2

                          Oh, that makes sense. In Qt5 there are two overloads of QProcess::finished. They were merged in Qt 6. In Qt5 you have to explicitly choose one, so either

                          connect(process, qOverload<int>(&QProcess::finished), this, [this, process](){
                          

                          or

                          connect(process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, [this, process](){
                          
                          J Offline
                          J Offline
                          JonexElectronic
                          wrote on 17 Jan 2023, 11:22 last edited by
                          #11

                          @Chris-Kawa said in Problem with Connect and Lambda functions:

                          connect(process, qOverload<int>(&QProcess::finished), this, this, process{

                          Thanks!! It works

                          C 1 Reply Last reply 17 Jan 2023, 13:27
                          0
                          • J JonexElectronic
                            17 Jan 2023, 11:22

                            @Chris-Kawa said in Problem with Connect and Lambda functions:

                            connect(process, qOverload<int>(&QProcess::finished), this, this, process{

                            Thanks!! It works

                            C Offline
                            C Offline
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on 17 Jan 2023, 13:27 last edited by
                            #12

                            @JonexElectronic Cool, no problem. The overload with just int is the one that is deprecated, so although more typing, it's better to use the other one. Fewer changes if you decide to update to Qt6 at some point. But either one is fine for now.

                            1 Reply Last reply
                            1

                            1/12

                            16 Jan 2023, 12:48

                            • Login

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