0

I start a QProcess in member function of a class but that object (Pdf object below) will soon get destroyed after creating the process. I obviously want the slot function to be available and called when QProcess finishes. I pass QProcess pointer so when it finishes, it will destroy it as well. But actually it doesn't really is destroyed when it finishes.

void PDf::createPDF()
{
PdfSymlink * pdfSymlink = new PdfSymlink( fileName, linkName, myProcess );

connect(myProcess, SIGNAL(finished(int)), pdfSymlink, SLOT(createPdfLink(int)) );

myProcess->start("sh",args); // args is defined now shown in code
} 

This is a repetitive code which is called many many timesI want the QProcess to get destroyed when it finishes and likewise pdfSymlink should be destroyed as well. How can I do that?

Note my slot does get called and it does the job but I want to make sure I clean up after this object.

zar
  • 11,361
  • 14
  • 96
  • 178

2 Answers2

1

Well, you seem to keep track of the process object. You could implement createPdfLink(int) like this:

void createPdfLink(int status)
{
    if(status != 0)
    {
       // Do error handling
    }
    else
    {
       // regular code
    }

    myProcess->deleteLater();
    deleteLater();
}

assuming myProcess is stored as myProcess inside the PdfSymlink object as well. It causes the process to be deleted by Qt as soon as it is allowed to be deleted by Qt (mainly to prevent random crashes) and causes the class itself to delete when allowed.

Extra:

As a more clean code, it might be better to include the connect function inside the constructor of the PdfSymlink class:

PdfSymlink::PdfSymlink(QString fileName, QString linkName, QProcess * myProcess)
{
    this->myProcess = myProcess;
    connect(myProcess, SIGNAL(finished(int)), SLOT(createPdfLink(int)));

    // More initialization code
}

This has the added benefit of keeping code relevant, and makes the "receiver" argument optional as the overloaded non-static member-function connect(sender,signal,method) is used.

Daniël Sonck
  • 869
  • 7
  • 9
  • This didn't work and I guess `deleteLater` is not working as advertised. It actually destroys the QProcess before it finishes with error message `QProcess: Destroyed while process ("sh") is still running.` If I remove `deleteLater` call my QProcess does finish and generate output. – zar Nov 05 '15 at 15:55
  • I will try some stuff when I get home, maybe "finished" isn't the best signal to use. – Daniël Sonck Nov 06 '15 at 17:04
  • Thanks, I have a solution that is working, I think I will post so it may help others but if you know of better, let me know – zar Nov 06 '15 at 20:03
1

So if anyone runs into the same issue I fix it, I had to call deleteLater as a slot:

void PDf::createPDF()
{
        QProcess *myProcess= new QProcess();

        PdfSymlink * pdfSymlink = new PdfSymlink( fileName, linkName, myProcess ); // fileName and LinkName definition is omitted 

        connect(myProcess, SIGNAL(finished(int)), pdfSymlink, SLOT(createPdfLink(int))

        // Call deleteLater
        connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()) );

        myProcess->start("sh",args); // args is defined now shown in code
} 
Xofo
  • 1,256
  • 4
  • 18
  • 33
zar
  • 11,361
  • 14
  • 96
  • 178
  • 1
    Just so anyone reading this solution. Please note that deleteLater(int) SLOT doesn't exist so in effect, deleteLater is never called. It is equivalent to not having the second connect. Probably this is shown on the terminal as "Could not connect QProcess::finished(int) to QProcess::deleteLater(int), no such slot" – Daniël Sonck Oct 19 '17 at 13:38