【问题标题】:Why QProcess::readAllStandardOutput reads NOT ALL output channel?为什么 QProcess::readAllStandardOutput 读取不是所有的输出通道?
【发布时间】:2020-03-18 21:59:13
【问题描述】:

我想将 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-&gt;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);
});

然后制作这个新的

但是有没有更优雅的解决方案可以一步读取标准输出?

【问题讨论】:

    标签: c++ qt file-io process widget


    【解决方案1】:

    一种可能的解决方案是让“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();
    

    【讨论】:

    • 我认为这可以称为问题的解决方案,虽然有点牵强。这种方式的好处是在处理finished()信号的槽中,可以解析top命令的输出,然后才再次调用top命令。
    猜你喜欢
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-06
    相关资源
    最近更新 更多