Problem with my class and QProcess
-
Hi all,
I want to create my own class to make it easier to execute powershell commands with QProcess. For testing, I wrote the code so that it returned to me the current location of the process (pwd).MyProcess myprocess; qDebug() << myprocess.RunCommand("pwd");
Unfortunately, the following errors appear to me:
qt.core.qobject.connect: QObject::connect: No such slot QObject::processStarted() in ..\WinConfigurator\myprocess.cpp:12qt.core.qobject.connect: QObject::connect: No such slot QObject::readyReadStandardOutput() in ..\WinConfigurator\myprocess.cpp:13
My class:
myprocess.h
#ifndef MYPROCESS_H #define MYPROCESS_H #include <QProcess> #include <QTime> #include <QCoreApplication> #include <QObject> class MyProcess : public QObject { public: MyProcess(); QStringList RunCommand(QString command); private slots: void processStarted(); void readyReadStandardOutput(); void encodingFinished(); private: QProcess* process; void SetupProcess(); void delay_MSec(unsigned int msec); bool process_ok; QStringList stream_data; }; #endif // MYPROCESS_H
myprocess.cpp
#include "myprocess.h" MyProcess::MyProcess() { SetupProcess(); } void MyProcess::SetupProcess() { process = new QProcess(this); process->setWorkingDirectory(qApp->applicationDirPath()); connect(process, SIGNAL(started()), this, SLOT(processStarted())); connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(readyReadStandardOutput())); connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus){ encodingFinished(); }); } void MyProcess::delay_MSec(unsigned int msec) { QTime _Timer = QTime::currentTime().addMSecs(msec); while( QTime::currentTime() < _Timer ) QCoreApplication::processEvents(QEventLoop::AllEvents, 100); } void MyProcess::processStarted() { qDebug() << "START"; stream_data.clear(); } void MyProcess::readyReadStandardOutput() { QString data = process->readAllStandardOutput(); stream_data << data; } void MyProcess::encodingFinished() { qDebug() << "END"; process_ok=true; } QStringList MyProcess::RunCommand(QString command) { QString cmd = "powershell.exe"; QStringList parameters{command}; process_ok=false; process->start(cmd, parameters); while(process_ok!=true) delay_MSec(100); process->close(); return stream_data; }
Does anyone know why I get these errors and how to solve it? Thank you in advance for your help!
-
@Piotrek102
Do the errors go away if you put theQ_OBJECT
macro into yourclass MyProcess
definition (and of course force rebuild)?On a separate note: it seems a shame you still use
SIGNAL
/SLOT
macros when your thirdconnect()
uses nicer new style syntax. -
@JonB said in Problem with my class and QProcess:
put the Q_OBJECT
forgot to mention it so i tried put the Q_OBJECT into my class. But I was getting other errors.
#ifndef MYPROCESS_H #define MYPROCESS_H #include <QProcess> #include <QTime> #include <QCoreApplication> #include <QObject> class MyProcess : public QObject { Q_OBJECT public: MyProcess(); QStringList RunCommand(QString command); private slots: void processStarted(); void readyReadStandardOutput(); void encodingFinished(); private: QProcess* process; void SetupProcess(); void delay_MSec(unsigned int msec); bool process_ok; QStringList stream_data; }; #endif // MYPROCESS_H
New errors:
debug/mainwindow.o:mainwindow.cpp (.rdata$.refptr._ZTV9MyProcess[.refptr._ZTV9MyProcess]+0x0): undefined reference to `vtable for MyProcess'collect2.exe: error: ld returned 1 exit status
[Makefile.Debug:88: debug/WinConfigurator.exe] Error 1
As for connect (), I'm learning all the time and hope my code will be better in the future
-
@JonB
Thank you so much, I forgot to rebuild my app. After rebuilding, everything works great! Thank you very much again! I mark the topic as solved.I would have written earlier but I had to wait 600 seconds to replay you one more time
-
@Piotrek102
I was not sure whether you needed theQ_OBJECT
macro. I had thought it was only required if the class emits signals, but yours seemed to be required because your class had slots, which I was not sure mattered. It seems it does!Yes, anytime you change anything about
Q_OBJECT
in a class you must do a full rebuild.undefined reference to 'vtable for MyProcess'
is the error you will get without rebuild.Your 3rd
connect()
uses the new-style syntax (with a lambda). You could rewrite the first two as:connect(process, &QProcess::started, this, &MyProcess::processStarted); connect(process, &QProcess::readyReadStandardOutput, this, &MyProcess::readyReadStandardOutput);
The advantage is that you get compile-time checking for compatibility. Then you will never (except in unusual circumstances) need to use
SIGNAL
orSLOT
macros again! -
Hi,
A full rebuild is not strictly required however running qmake before building is when adding or removing the Q_OBJECT macro as moc must do its job when added and otherwise not run when removed. But when I doubt, full rebuild often helps.