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 Updated to NodeBB v4.3 + New Features

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 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??

    JonBJ 1 Reply Last reply
    0
    • J JonexElectronic

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

      Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on 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
      3
      • Axel SpoerlA Offline
        Axel SpoerlA Offline
        Axel Spoerl
        Moderators
        wrote on 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
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by Chris Kawa
          #3

          Is ProcessController derived from QObject?

          J 1 Reply Last reply
          1
          • Chris KawaC Chris Kawa

            Is ProcessController derived from QObject?

            J Offline
            J Offline
            JonexElectronic
            wrote on last edited by
            #4

            @Chris-Kawa Yes it is

            1 Reply Last reply
            0
            • Axel SpoerlA Axel Spoerl

              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 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();
              }
              
              Chris KawaC 1 Reply Last reply
              0
              • fcarneyF Offline
                fcarneyF Offline
                fcarney
                wrote on 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

                  @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();
                  }
                  
                  Chris KawaC Offline
                  Chris KawaC Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on 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
                  4
                  • Chris KawaC Chris Kawa

                    @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 last edited by
                    #8

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

                    Chris KawaC 1 Reply Last reply
                    0
                    • J JonexElectronic

                      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??

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on 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

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

                        Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on 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
                        3
                        • Chris KawaC Chris Kawa

                          @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 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

                          Chris KawaC 1 Reply Last reply
                          0
                          • J JonexElectronic

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

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

                            Thanks!! It works

                            Chris KawaC Offline
                            Chris KawaC Offline
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on 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

                            • Login

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