问题
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.
回答1:
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"
来源:https://stackoverflow.com/questions/4629185/launch-and-write-to-terminal-in-qt