【问题标题】:Launch and write to terminal in Qt在 Qt 中启动并写入终端
【发布时间】:2011-01-07 18:58:43
【问题描述】:

我正在使用 Qt 在 linux 中编码。我知道使用 popen 或 QProcess 我可以从我的程序中启动终端,但是我该如何写入呢?我谷歌周围的人都在建议 fork() 和 pipe()。 我的目的是对终端进行 ICMP ping,并在 ping 成功时停止。我用 popen 成功了,但我无法停止 ping 过程,因此我的程序无法运行。

【问题讨论】:

    标签: qt popen ping qprocess


    【解决方案1】:

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

    来自ping(8) - Linux man page

    如果 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(表示成功),就会发出 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"
    

    【讨论】:

    • 感谢您的回答,非常有帮助!但是我不明白,我们不是必须将程序路径或其他东西传递给 QProcess::start 吗?您正在传递字符串“ping”,它是如何工作的?
    • 你是对的,我们必须将程序路径作为参数传递给QProcess::start。在示例中,它只是 ping,因为如果 ping 程序位于 PATH 环境变量中列出的目录之一中就足够了。但是,如果不是,或者您不想依靠 PATH 变量,则必须提供完整路径。顺便一提;您可能希望接受我的回答作为您问题的解决方案。
    • 是的,我正在使用您提供的答案,我尝试 ping google 并返回:("-c", "5", "209.85.175.147") QProcess: Destroyed while process is仍在运行。 0 1 "PING 209.85.175.147 (209.85.175.147) 56(84) 字节数据。来自 209.85.175.147 的 64 字节:icmp_seq=1 ttl=56 time=21.5 ms" Ping 成功但是当我尝试 ping 未连接的东西时,它返回: ("-c", "5", "192.168.1.100") QProcess: Destroyed while process仍在运行。 0 1 "" Ping 成功了我有什么遗漏吗?
    • 抱歉代码混乱。我是说当我ping连接和未连接的源时,返回的退出代码是0,QProcess状态是1,都说“ping成功”。
    猜你喜欢
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 2016-07-19
    • 1970-01-01
    • 2017-10-09
    相关资源
    最近更新 更多