Qt:如何捕获系统调用的错误

Qt: How to catch an error with system call?

本文关键字:错误 系统调用 何捕获 Qt      更新时间:2023-10-16

我正在构建一个GUI应用程序,我在其中进行系统调用并调用gnuplot来运行脚本。现在我想构建一条错误消息,说明何时出现问题(例如,gnuplot 未安装或路径错误)。

所以我一直在考虑只推出一个 QMessageBox,但我不知道如何检查系统调用是否成功。

if(//System call didn't work)
{
    QMessageBox msgBox;
    msgBox.setWindowTitle("Error");
    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setText("GNUPLOT was not installed");
    msgBox.exec();
}

我的系统调用如下所示:

system(gnuplot script.txt);

有什么建议吗?

你应该使用QProcess而不是低级系统调用,因为它在Qt代码库中是一个很好的抽象。否则,您最终将处理特定于平台的位。 QProcess已经为您解决了这个问题。如果您碰巧可以使用阻止方法,则。同步,你可以在下面写一些类似代码的东西。

QProcess process;
process1.start("gnuplot arg1 arg2 etc");
// Wait for it to start
if(!process.waitForStarted())
    return 0;
bool retval = false;
QByteArray buffer;
while ((retval = process.waitForFinished()));
    buffer.append(process.readAll());
if (!retval) {
    qDebug() << "Process 2 error:" << process.errorString();
    msgBox.setText(buffer);
    return 1;
}

如果您不想在 gnuplot 脚本运行时阻塞,您可以将一个插槽或简单地使用 C++11 及 的 lambda 连接到 readyRead() 信号。当然,您还需要连接到 error() 信号。没有 lambda 的 lambda 可用于 C++11 之前的环境的代码如下所示:

GnuPlotReader::GnuPlotReader(QQProcess *process, QObject *parent)
    : QObject(parent)
    , m_process(process)
    , m_standardOutput(stdout)
{
    connect(m_process, SIGNAL(readyRead()), SLOT(handleReadyRead()));
    connect(m_process, SIGNAL(error(QProcess::ProcessError)), SLOT(handleError(QProcess::ProcessError)));
    connect(&m_timer, SIGNAL(timeout()), SLOT(handleTimeout()));
    m_timer.start(5000);
}
GnuPlotReader::~GnuPlotReader()
{
}
void GnuPlotReader::handleReadyRead()
{
    m_readData = m_process->readAll();
    if (!m_timer.isActive())
        m_timer.start(5000);
}
void GnuPlotReader::handleTimeout()
{
    if (m_readData.isEmpty()) {
        m_standardOutput << QObject::tr("No data was currently available for reading from gnuplot") << endl;
    } else {
        m_standardOutput << QObject::tr("GnuPlot successfully run")<< endl;
    }
}
void GnuPlotReader::handleError(QProcess::ProcessError processError)
{
    if (processError == QProcess::ReadError) {
        m_standardOutput << QObject::tr("An I/O error occurred while reading the data, error: %2").arg(m_process->errorString()) << endl;
        messageBox.setText(m_readData);
    }
}