实现界面及在Windows 10下的运行结果如下:
代码如下:
pingNetWork.h
// 检测网络是否ping通的工具
#ifndef PINGNETWORK_H
#define PINGNETWORK_H
#include <QWidget>
#include"control_global.h"
namespace Ui {
class CPingNetWork;
}
class CONTROL_EXPORT CPingNetWork : public QWidget
{
Q_OBJECT
public:
explicit CPingNetWork(QWidget *parent = nullptr);
~CPingNetWork();
signals:
void pingResultSignal(const QString&qsPingRst);
private:
void initUI();
void pingSlot();
void clearResultSlot();
void pingThreadFun(const QString&destIp);
void pingResult(const QString& qsPingRst);
private:
Ui::CPingNetWork *ui;
bool m_bPing{true};
};
#endif // PINGNETWORK_H
pingNetWork.cpp
#include "pingNetWork.h"
#include "ui_pingNetWork.h"
#include<QRegExp>
#include<QRegExpValidator>
#include<thread>
#include<QProcess>
using namespace std::literals;
CPingNetWork::CPingNetWork(QWidget *parent) :
QWidget(parent),
ui(new Ui::CPingNetWork)
{
ui->setupUi(this);
initUI();
connect(ui->startPingBtn, &QAbstractButton::clicked, this, &CPingNetWork::pingSlot);
connect(this, &CPingNetWork::pingResultSignal, this, &CPingNetWork::pingResult);
connect(ui->clearResultBtn, &QAbstractButton::clicked, this, &CPingNetWork::clearResultSlot);
}
CPingNetWork::~CPingNetWork()
{
m_bPing = false;
delete ui;
}
void CPingNetWork::initUI()
{
ui->startPingBtn->setFixedSize(120, 60);
ui->IPLineEdit->setFixedWidth(220);
ui->clearResultBtn->setFixedSize(120, 60);
ui->clearResultBtn->setFixedWidth(220);
QRegExp rx("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
auto pExpValidator = new QRegExpValidator(rx, this);
ui->IPLineEdit->setValidator(pExpValidator);
ui->IPLineEdit->setText(QLatin1String("127.0.0.1"));
}
void CPingNetWork::clearResultSlot()
{
ui->networkTestRst->clear();
}
void CPingNetWork::pingSlot()
{
if(!ui->startPingBtn->text().compare(QStringLiteral("开始Ping(&P)")))
{
m_bPing = true;
ui->startPingBtn->setText(QStringLiteral("停止Ping(&W)"));
auto destIp = ui->IPLineEdit->text();
// 开启一个线程,用来一直ping
std::thread pingThread(&CPingNetWork::pingThreadFun, this, destIp);
pingThread.detach();
}
else
{
m_bPing = false;
ui->startPingBtn->setText(QStringLiteral("开始Ping(&P)"));
}
}
void CPingNetWork::pingResult(const QString& qsPingRst)
{
ui->networkTestRst->append(qsPingRst);
}
void CPingNetWork::pingThreadFun(const QString&destIp)
{
QProcess pingProcess;
QString strArg, qsStdout;
#ifdef Q_OS_WIN // "ping IP -n 1 -i 2 "只Windows支持,linux不支持
strArg = QLatin1String("ping ") + destIp + QLatin1String(" -n 1 -i 2");
pingProcess.start(strArg, QIODevice::ReadOnly);
pingProcess.waitForFinished(-1);
qsStdout = QString::fromLocal8Bit(pingProcess.readAllStandardOutput());
emit pingResultSignal(qsStdout);
#endif
// windows、Linux连续ping命令格式不同,需要区分
#ifdef Q_OS_WIN
strArg = QLatin1String("ping ") + destIp + QLatin1String(" -t");
#elif Q_OS_UNIX
strArg = QLatin1String("ping ") + destIp;
#endif
while (m_bPing)
{
pingProcess.start(strArg, QIODevice::ReadOnly);
pingProcess.waitForFinished(300);
qsStdout = QString::fromLocal8Bit(pingProcess.readAllStandardOutput());
#ifdef Q_OS_WIN // windows两次ping返回的报文之间有时会插入空行,过滤掉
auto index = qsStdout.indexOf("\r\n");
if(-1 == index)
{
continue;
}
#endif
emit pingResultSignal(qsStdout);
std::this_thread::sleep_for(800ms);
}
}
说明:
- ui->IPLineEdit用来输入ping的目的机器的IP地址。其通过36行的正则表达式限定只能输入IP地址格式的数字,该正则表达式的具体含义,参见:利用QLineEdit的正则表达式校验器显示IP地址 博文。
- ui->startPingBtn、ui->clearResultBtn分别是上述界面的“开始ping”、“清除结果”按钮。
- 程序难懂的部分作了注释,程序很容易看懂,不再具体描述。
文章评论