I am new to QThread I have a Application in which we can run Qthread::run() from Class "buildScript" Where BuildScriptThread class is inherited from Qthread.
I have to run thread till till it satisfy some condition e.g While(tillfalse()) in run() in BuildScriptThread Class.
Inside While I have to Call QProcess to excute some command with some parameter pass. in run() .Some times after excuting 5,6 times Application crashes with Output :
warning: QObject: Cannot create children for a parent that is in a different thread. (Parent is QProcess(0x2f8cb00), parent's thread is QThread(0x698198), current thread is BuildScriptThread(0x6d40e8)
So please have a look:::
Class BuildScriptThread header file
class BuildScriptThread : public QThread
{
Q_OBJECT
private:
QProcess *buildProc;
QString buildDirectory;
private slots:
void readStdOutput();
public:
BuildScriptThread(MainWindow *mainWin);
~BuildScriptThread();
void CurrentXmlModule(QString module);
public:
void run();
QStringList BuildPrameter();
QString killCurrentProcess();
bool isAllListEmpty();
void interruptibleCall();
protected:
void interruptible();
signals:
void updateStatus(QString );
void buildScriptCompleted();
};
BuildScriptThread::BuildScriptThread(MainWindow *mainWin)
{
stopped = false;
mainWindow=mainWin;
buildProc = new QProcess();
xmlModuleStruct.verModuleFlag =false;
//Define slot for ready standard output data signal
connect(buildProc, SIGNAL(readyReadStandardOutput()), this, SLOT(readStdOutput()));
}
BuildScriptThread::~BuildScriptThread()
{
//Disconnect the ready standard output data signal
disconnect(buildProc, SIGNAL(readyReadStandardOutput()), this, SLOT(readStdOutput()));
delete buildProc;
buildProc = NULL;
}
void BuildScriptThread::run()
{
QString setdirectory = mainWindow->getDirectory();
setdirectory.remove(setdirectory.indexOf("/veri"),13);
QDir::setCurrent(setdirectory);
while(!isAllListEmpty()){
QThread::sleep(1);
qDebug() << killCurrentProcess();
buildProc->setProcessChannelMode(QProcess::MergedChannels);
QStringList buildPram = QStringList() << BuildPrameter();
QThread::usleep(500);
buildProc->start("script.bat",buildPram);
if (!buildProc->waitForFinished(-1))
{
QString errMsg = buildProc->errorString().append(": ").append(buildScriptName);
emit updateStatus(errMsg);
}
QThread::usleep(500);
}
emit buildScriptCompleted();
QDir::setCurrent(currentPath);
}
void BuildScriptThread::readStdOutput()
{
QByteArray data = buildProc->readAllStandardOutput();
}
QString BuildScriptThread::killCurrentProcess(){
int PID = buildProc->processId();
if(PID > 0){
QString str1 = QString("taskkill /PID %1 /f").arg(PID);
QProcess::execute(str1);
return "Terminating Thread";
}else{
qDebug() << "PID is Zero";
return "Process Is not Running";
}
delete buildProc;
buildProc = NULL;
buildProc = new QProcess();
}
bool BuildScriptThread::isAllListEmpty()
{
return (xmlModuleStruct.List1.isEmpty() & xmlModuleStruct.List2.isEmpty() & xmlModuleStruct.List2.isEmpty());
}
void BuildScriptThread::interruptibleCall()
{
interruptible();
}
void BuildScriptThread::interruptible()
{
this->setTerminationEnabled(false);
}
Header File
class BuildScript : public QObject
{
Q_OBJECT
public:
BuildScript(QObject* parent=0, MainWindow *minWin=0);
~BuildScript();
void startRun();
private:
BuildScriptThread *buildScriptThread;
MainWindow *mainWindow;
signals:
void buildScriptCompleted();
void updateStatus(QString);
void UpdateWindowtile();
public slots:
void abortThread();
};
Source File
BuildScript::BuildScript(QObject *parent, MainWindow *minWin)
:QObject (parent)
{
mainWindow = minWin;
buildScriptThread = new BuildScriptThread(minWin);
buildScriptThread->interruptibleCall();
connect(buildScriptThread,SIGNAL(updateStatus(QString)),this,SIGNAL(updateStatus(QString)));
connect(buildScriptThread, SIGNAL(buildScriptCompleted()),this, SIGNAL(buildScriptCompleted()));
connect(mainWindow,SIGNAL(abortThread()),this,SLOT(abortThread()));
}
BuildScript::~BuildScript()
{
disconnect(buildScriptThread,SIGNAL(updateStatus(QString)),this,SIGNAL(updateStatus(QString)));
disconnect(buildScriptThread, SIGNAL(buildScriptCompleted()),this, SIGNAL(buildScriptCompleted()));
}
void BuildScript::startRun
{
buildScriptThread->start();
}
void BuildScript::abortThread()
{
qDebug() << "Terminating";
if(buildScriptThread->isRunning()){
qDebug() << buildScriptThread->killCurrentProcess();
buildScriptThread->terminate();
emit buildScriptCompleted();
}else{
emit UpdateWindowtile();
}
}