为什么 QProcess::readAllStandardOutput 读取的不是所有输出通道?

Why QProcess::readAllStandardOutput reads NOT ALL output channel?

我想将 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 秒,等待下一次 top 更新的时间为 3 - 4 秒。这就是为什么我添加 QThread::msleep(1000); - 只是为了在 QTextEdit 中看到这个闪烁 并完全认识到那是数据写入(如果总结所有 5 秒内交易)。

  2. qDebug() 显示下一张图片(第 1 个数字 -> [1 秒] -> 第 2 个数字 -> [3 秒] -> 第 4 个数字 -> [1 秒] -> ...):

看起来 readAllStandardOutput(); 没有读取所有标准输出,而是读取了 4096 字节,然后才读取剩下的字节(大约 14000,即没有一些读取缓冲区限制)!

所以我无法在我的 QTextEdit 中显示 top 命令的完整输出:) 请帮我做这个!

更新:

添加 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);
});

并制作这个新的

但是是否有更优雅的解决方案允许单步读取标准输出?

一个可能的解决方案是使"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();