简体   繁体   English

问:如何通过系统调用捕获错误?

[英]Qt: How to catch an error with system call?

I am building a GUI application where I do a system call and call for gnuplot to run a script. 我正在构建一个GUI应用程序,我在其中进行系统调用并调用gnuplot来运行脚本。 Now i want to build in an error message that says when something is wrong (eg gnuplot is not installed or in the wrong path). 现在我想构建一个错误消息,说明什么时候出错(例如没有安装gnuplot或者路径错误)。

So I've been thinking about just putting out a QMessageBox, but I don't know how I can check whether the system call succeeded or not. 所以我一直在考虑推出一个QMessageBox,但我不知道如何检查系统调用是否成功。

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

My system call looks like this: 我的系统调用如下所示:

system(gnuplot script.txt);

Any suggestions? 有什么建议?

You should use QProcess rather than low-level system call because it is a nice abstraction in a Qt codebase. 您应该使用QProcess而不是低级系统调用,因为它是Qt代码库中的一个很好的抽象。 Otherwise, you will end up dealing with platform specific bits. 否则,您将最终处理特定于平台的位。 QProcess already solves that for you. QProcess已经为您解决了这个问题。 If you happen to be fine with a blocking approach, aka. 如果你恰好使用阻塞方法,也就是说。 sync, you could write something like that code below. 同步,你可以写下面的代码。

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;
}

If you would not like to block while the gnuplot script of yours is running, you could connect a slot, or simply lambda with C++11 and on, to the readyRead() signal. 如果你不想在你的gnuplot脚本运行时阻塞,你可以将一个插槽或简单的lambda与C ++ 11连接到readyRead()信号。 For sure, you would also need to connect to the error() signal. 当然,您还需要连接到error()信号。 The code without lambda to work with pre C++11 environments would look something like this: 没有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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM