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