Почему QProcess :: readAllStandardOutput читает НЕ ВСЕ выходной канал? - PullRequest
2 голосов
/ 19 марта 2020

Я хочу добавить вывод из инструмента top linux в QTextEdit. Вывод top очень велик - возможно, именно поэтому код:

m_pprocess = new QProcess();
m_pprocess->setCurrentWriteChannel(QProcess::StandardOutput);
m_pprocess->start("top -b -d 5.0");

connect(m_pprocess, &QProcess::readyReadStandardOutput, [this](){

    m_ptexteditProcesses->clear();
    QThread::msleep(1000);
    QByteArray ba = m_pprocess->readAllStandardOutput();
    m_ptexteditProcesses->append(ba);
    qDebug() << ba.size();
    m_ptexteditProcesses->verticalScrollBar()->triggerAction(QScrollBar::SliderToMinimum);
});

ведет себя следующим образом:

  1. Несмотря на период обновления для команды top 5 секунд, мой QTextEdit обновляется дважды с периодом 1 секунда, а ожидание осталось 3 - 4 секунды для следующего top обновления. Вот почему я добавляю QThread::msleep(1000); - просто чтобы увидеть это мигание в QTextEdit и полностью распознать запись данных (если суммировать все транзакции за 5 секунд).

  2. qDebug() показать мне следующее изображение (1-е число -> [1 с] -> 2-е число -> [3 с] -> 4-е число -> [1 с] -> ...):

QByteBuffer size

Похоже, что readAllStandardOutput(); читает не весь стандартный вывод, а 4096 байтов, и только затем читает оставшиеся байты (что составляет около 14000, т.е. некоторые ограничения на чтение буфера)!

Так что я не могу показать весь вывод команды top в моем QTextEdit :) Пожалуйста, помогите мне сделать это!

ОБНОВЛЕНИЕ :

Добавление m_pprocess->waitForReadyRead(1); может быть немного исправлено, как

connect(m_pprocess, &QProcess::readyReadStandardOutput, [this](){

    m_ptexteditProcesses->clear();
    //QThread::msleep(1000);
    QByteArray ba;
    m_pprocess->waitForReadyRead(1);
    ba.append(m_pprocess->readAllStandardOutput());
    m_ptexteditProcesses->append(ba);
    qDebug() << ba.size();
    m_ptexteditProcesses->verticalScrollBar()->triggerAction(QScrollBar::SliderToMinimum);
});

И произвести этот новый

, но Есть ли более элегантное решение, которое позволяет читать стандартный вывод за один шаг?

1 Ответ

1 голос
/ 19 марта 2020

Одно из возможных решений состоит в том, чтобы заставить команду top запускаться один раз, а когда команда заканчивает чтение всей информации, и читать ее каждые T секунд, тогда можно использовать QTimer:

m_pprocess = new QProcess();
m_pprocess->setCurrentWriteChannel(QProcess::StandardOutput);
m_pprocess->setProgram("top");
m_pprocess->setArguments({"-bn1"});

m_ptimer = new QTimer;
m_ptimer->setSingleShot(true);
m_ptimer->setInterval(5000);
connect(m_ptimer, &QTimer::timeout, m_pprocess, [this]{
    m_pprocess->start();
});

connect(m_pprocess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [this](){
    m_ptexteditProcesses->clear();
    QByteArray ba = m_pprocess->readAllStandardOutput();
    m_ptexteditProcesses->append(ba);
    qDebug() << ba.size();
    m_ptexteditProcesses->verticalScrollBar()->triggerAction(QScrollBar::SliderToMinimum);
    m_ptimer->start();
});

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