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.3k 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.
  • 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