0

What I'm trying to do is launch a program within another program using QProcess and then save the output from the launched program into a QTextEdit of the launcher program. Every time I launch this program I want it to add more text to the QTextEdit. Now I get the program to launch but then after the text is supposed to be written it crashes. Here is the code:

#include <QWidget>
#include <QPushButton>
#include <QTextEdit>
#include <QProcess>
#include <QVBoxLayout>
#include <QApplication>

class Widget : public QWidget
{
    Q_OBJECT
    QTextEdit* text;
public:
    Widget() : text(new QTextEdit) {
        QPushButton* addBtn = new QPushButton("Add Module");
        text->setReadOnly(true);
        QVBoxLayout* layout = new QVBoxLayout(this);
        layout->addWidget(addBtn,0);
        layout->addWidget(text);
        connect(addBtn,SIGNAL(clicked()),SLOT(launchModule()));
    }
    Q_SLOT void launchModule() {
        QString program = "C:/A2Q2-build-desktop/debug/A2Q1.exe";
        QProcess *myProcess = new QProcess(this);
        connect(myProcess, SIGNAL(finished(int)), SLOT(finished()));
        connect(myProcess, SIGNAL(error(QProcess::ProcessError)), SLOT(finished()));
        myProcess->start(program);
    }
    Q_SLOT void finished() {
        QProcess *process = qobject_cast<QProcess*>(sender());
        QString out = process->readAllStandardOutput(); // will be empty if the process failed to start
        text->append(out);
        delete process;
    }
};

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    Widget w;
    w.show();
    app.exec();
}

#include "main.moc"
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
Dmon
  • 220
  • 4
  • 15

2 Answers2

3

It's crashing because you're deleting the sender object while inside a slot. Instead of delete process, you should

process->deleteLater();

For logging purposes you should be using QPlainTextEdit instead of a QTextEdit. The former is faster. You're prematurely pessimizing by using the latter. Alas, even QPlainTextEdit becomes abysmally slow if you're sending about 100 lines/s (at least on Qt 4.8). If you want a really fast log view, you'll need to use QListWidget, with a caveat, or roll your own.

I have a complete example of how to send to and receive from a process in another answer.

Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • ok now I know, thank you. I have changed the other program now but it is still not capturing the output. Here is the output function of the other program: void StudentForm::output(){ stuNum = stuEdt->text().toInt(); mark = markSbx->text().toInt(); modCode = codeEdt->text(); QString t = tr("Student number:%1 Module Code: %2 Mark: %3").arg(stuNum).arg(modCode).arg(mark); qDebug() << t; } – Dmon Sep 11 '13 at 02:47
  • 1
    You're supposed to be outputting to standard output, not using `qDebug()`. You can have a global `QTextStream out(stdout);`, then `out << t`. See the other answer I linked to in the edit. – Kuba hasn't forgotten Monica Sep 11 '13 at 12:39
1

The process is crashing because you're deleting the parent from within the finished slot.

Also, it's probably easier to do something like this:

QObject::connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(getOutput()));

instead of using the finished() slot. But that's more personal preference than anything.

Tyler Jandreau
  • 4,245
  • 1
  • 22
  • 47