在 Qt 中启动并写入终端

发布于 2024-10-11 08:48:46 字数 184 浏览 6 评论 0原文

我正在使用 Qt 在 Linux 中编码。我知道使用 popen 或 QProcess 我可以从我的程序启动终端,但如何写入它?我用谷歌搜索了一下,人们建议使用 fork() 和 pipeline()。 我的目的是与终端进行 ICMP ping,并在 ping 成功时停止。我用 popen 做到了,但我无法停止 ping 过程,因此我的程序无法运行。

I am coding in linux using Qt. I understand that with popen or QProcess I can launch terminal from my program, but how do I write into to it? I google around people are suggesting fork() and pipe().
My purpose is to do an ICMP ping with the terminal, and stop when ping successfully. I made it with popen, but I couldn't stop the ping process thus my program won't run.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我也只是我 2024-10-18 08:48:46

您不会向终端写入任何内容,因为没有终端。您将要运行的程序的名称及其参数作为 QProcess 的参数传递::start 方法。如果您只需要知道 ping 是否成功,那么检查您之前使用 QProcess::start 启动的进程的退出代码就足够了;你不必阅读它的输出。

来自 ping(8) - Linux 手册页

如果 ping 没有收到任何回复
数据包全部退出时都会带有代码
1. 如果同时指定了数据包计数和截止时间,且小于计数
数据包被接收到的时间
截止日期已到,也将
退出并显示代码 1。出现其他错误时
退出并显示代码 2。否则退出
代码为 0。这使得可以
使用退出代码来查看主机是否
生与死。

默认情况下,Linux 下的 ping 会一直运行,直到您停止为止。但是,您可以使用 -c X 选项仅发送 X 个数据包,并使用 -w X 选项将整个过程的超时设置为 X 秒。这样您就可以限制 ping 运行的时间。
下面是使用 QProcess 在 Windows 上运行 ping 程序的工作示例。对于 Linux,您必须相应地更改 ping 选项(例如将 -n 更改为 -c)。在示例中,ping 运行了 X 次,其中 X 是您为 Ping 类构造函数提供的选项。一旦这些执行中的任何一个以退出代码 0(表示成功)返回,就会发出值为 true 的 result 信号。如果没有执行成功,则发出 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"

You don't write anything to terminal because there's no terminal. You pass name of a program to run and its arguments as arguments of the QProcess::start method. If you only need to know if ping was successful or not it's enough to check the exit code of the process which you started earlier using QProcess::start; you don't have to read its output.

from ping(8) - Linux man page

If ping does not receive any reply
packets at all it will exit with code
1. If a packet count and deadline are both specified, and fewer than count
packets are received by the time the
deadline has arrived, it will also
exit with code 1. On other error it
exits with code 2. Otherwise it exits
with code 0. This makes it possible to
use the exit code to see if a host is
alive or not.

By default ping under Linux runs until you stop it. You can however use -c X option to send only X packets and -w X option to set timeout of the whole process to X seconds. This way you can limit the time ping will take to run.
Below is a working example of using QProcess to run ping program on Windows. For Linux you have to change ping options accordingly (for example -n to -c). In the example, ping is run up to X times, where X is the option you give to Ping class constructor. As soon as any of these executions returns with exit code 0 (meaning success) the result signal is emitted with value true. If no execution is successful the result signal is emitted with value 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"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文