Qt: есть ли способ отправить сигнал, когда QProcess записывает строку в стандартный вывод - PullRequest
4 голосов
/ 08 июня 2011

Я нашел похожие вопросы, но никогда не получил точного ответа.У меня есть программа Qt, которая запускает QProcess и записывает вывод в окно QTextEdit, пока все хорошо.Но это происходит только после завершения программы.если возможно, я бы хотел, чтобы стандартный вывод программ печатался в реальном времени.В идеальном мире был бы некоторый сигнал, который QProcess испускает, когда есть готовая строка для чтения, если это невозможно с QProcess, возможно ли это вообще?Кроме того, в идеале вы могли бы по-прежнему использовать оставшуюся часть программы во время выполнения процесса.

Вот часть кода, который у меня есть, очень простой, он просто выдает первую строку стандартного вывода QProcess в QTextEdit

...
extProcess::extProcess(QObject *parent) :
    QObject(parent)
    extProcess::extProcess(QObject *parent) :
    QObject(parent)
{
    proc = new QProcess(this); //initialize proc
    arguments << "-v";
    connect(proc, SIGNAL(readyRead()), this, SLOT(logReady()));

}

void extProcess::startProcess()
{
    emit clearLog();
    emit outLog("--Process started--");
    proc->start("/Users/jonathan/Desktop/testgg");
}

void extProcess::logReady()
{
       emit outLog(proc->readLine());
}
...

Это альтернативная версия, которую я пробовал, она будет отображать весь вывод QProcess, но будет отображаться только после завершения программы.

    ...
    extProcess::extProcess(QObject *parent) :
    QObject(parent)

{
    proc = new QProcess(this); //initialize proc
    proc->setProcessChannelMode(QProcess::SeparateChannels);
    arguments << "-v";
    connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(logReady()));

}


void extProcess::logReady()
{

       while(proc->bytesAvailable()){
               emit outLog(proc->readLine());
       }
}



void extProcess::startProcess()
{
    emit clearLog();
    emit outLog("--Process started--");
    proc->start("/Users/jonathan/Desktop/testgg");
}



void extProcess::killProcess()
{
    proc->terminate();
    emit clearLog();
    emit outLog("--Process Terminated--");
}
....

Спасибо

Ответы [ 3 ]

6 голосов
/ 08 июня 2011

Я использую readAllStandardOutput () для этой конкретной цели, и это работает для меня.

Однако я заметил, что он не получит никакого стандартного вывода до тех пор, пока процесс на самом деле не очистит свой выходной буфер («\ n» может не делать этого автоматически, по крайней мере, в моем случае с Windows, полностью зависящем от платформы).

В зависимости от того, как дочерний процесс записывает свой вывод (приложение C или приложение C ++), он должен вызывать fflush(stdout); или заканчивать строки с std::endl; соответственно.

3 голосов
/ 08 июня 2011

readLine () , вероятно, ожидает, пока не будет прочитан первый символ '\ n'.

readAllStandardOutput , с другой стороны, возвращает все данные, доступные из стандартного вывода процесса.

Так что мне кажется, что если вы используете readAllStandardOutput (), вы можете получить больше производительности.

Вы должны попробовать, хотя.

2 голосов
/ 08 июня 2011

В идеальном мире был бы какой-то сигнал, который QProcess излучает, когда есть строка, готовая для чтения

Является ли сигнал Qprocess readyReadStandardOutput() не совсем тем, что выспрашивать?

Вы можете подключиться к нему, тогда ваш слот получит доступные данные bytesAvailable() и ищет символы '/n'.Или просто readLine(), а canReadLine().

Не забудьте запустить процесс и не ждите его завершения.Кроме того, установите ProcessChannelMode в SeparateChannels.

РЕДАКТИРОВАТЬ

У меня есть класс, который читает строку QProcess, например:

bool extProcess::logReady()
{
    while( proc->canReadLine())
    {
        QByteArray line = proc->readLine();
        /*do some with the line like copying it's content to a QTextEdit*/
    }
}

И это работает довольно хорошо. Я не уверен насчет сигнала emit outLog()! Вы пытаетесь пропустить QByteArray через сигнал?Данные, содержащиеся в QByteArray, должны быть сохранены в буфере, и вы должны передать указатель на этот массив любому, кто к нему подключен ...

Но опять же, если вы не хотите использовать дополнительную память иразобраться с «потребляются ли данные? ...», делать то, что вам нужно делать с данными в вашем методе logReady().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...