Запустите и напишите на терминал в Qt - PullRequest
1 голос
/ 07 января 2011

Я пишу в Linux с использованием Qt. Я понимаю, что с помощью popen или QProcess я могу запустить терминал из моей программы, но как мне в него записать? Я гуглю вокруг людей, которые предлагают fork () и pipe (). Моя цель - выполнить ICMP-пинг с терминалом и остановиться при успешном пинге. Я сделал это с помощью popen, но я не смог остановить процесс ping, поэтому моя программа не запустилась.

1 Ответ

1 голос
/ 08 января 2011

Вы ничего не пишите в терминал, потому что нет терминала. Вы передаете имя программы для запуска и ее аргументы в качестве аргументов метода QProcess::start. Если вам нужно знать, был ли ping успешным или нет, достаточно проверить код завершения процесса, который вы запустили ранее, используя QProcess::start; вам не нужно читать его вывод.

из ping (8) - справочная страница Linux

Если пинг не получает ответа пакеты вообще будут выходить с кодом 1. Если количество пакетов и срок указаны и меньше, чем количество пакеты принимаются к тому времени срок истек, он также будет выход с кодом 1. На другую ошибку это выходит с кодом 2. В противном случае он выходит с кодом 0. Это позволяет используйте код выхода, чтобы увидеть, является ли хост жив или нет.

По умолчанию ping под Linux работает до тех пор, пока вы его не остановите. Однако вы можете использовать опцию -c X для отправки только X пакетов и опцию -w X для установки времени ожидания всего процесса равным X секундам. Таким образом, вы можете ограничить время выполнения команды ping.
Ниже приведен рабочий пример использования QProcess для запуска программы ping в Windows. Для Linux вы должны соответственно изменить параметры ping (например, -n на -c). В этом примере ping запускается до X раз, где X - это опция, которую вы даете Ping конструктору класса. Как только любое из этих выполнений возвращается с кодом выхода 0 (что означает успех), сигнал result отправляется со значением true. Если выполнение не было успешным, сигнал result излучается со значением false.

#include <QCoreApplication>
#include <QObject>
#include <QProcess>
#include <QTimer>
#include <QDebug>


class Ping : public QObject {

    Q_OBJECT

public:

    Ping(int count)
    : QObject(), count_(count) {

        arguments_ << "-n" << "1" << "example.com";

        QObject::connect(&process_,
                         SIGNAL(finished(int, QProcess::ExitStatus)),
                         this,
                         SLOT(handlePingOutput(int, QProcess::ExitStatus)));
    };

public slots:

    void handlePingOutput(int exitCode, QProcess::ExitStatus exitStatus) {
        qDebug() << exitCode;
        qDebug() << exitStatus;
        qDebug() << static_cast<QIODevice*>(QObject::sender())->readAll();
        if (!exitCode) {
            emit result(true);
        } else {
            if (--count_) {
                QTimer::singleShot(1000, this, SLOT(ping()));
            } else {
                emit result(false);
            }
        }
    }

    void ping() {
        process_.start("ping", arguments_);
    }

signals:

    void result(bool res);

private:

    QProcess process_;
    QStringList arguments_;
    int count_;
};


class Test : public QObject {

    Q_OBJECT

public:
    Test() : QObject() {};

public slots:
    void handle(bool result) {
        if (result)
            qDebug() << "Ping suceeded";
        else
            qDebug() << "Ping failed";
    }
};


int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    Test test;
    Ping ping(3);
    QObject::connect(&ping,
                     SIGNAL(result(bool)),
                     &test,
                     SLOT(handle(bool)));

    ping.ping();
    app.exec();
}

#include "main.moc"
...