实现步骤:
在Qt Creator中新建一个Qt Widgets应用程序项目,并添加一个MainWindow窗口。
在MainWindow中设计需要的界面,包括按钮、文本框等控件。
编写udp通信代码,包括bind绑定和数据接收。在udp通信类中使用QThread的moveToThread函数将数据接收放到单独的线程中执行。
在点击按钮时,判断是否成功连接了udp通信,如果成功则跳转到主界面;否则提示用户未成功连接。
在主界面处理接收到的数据,并利用QCustomPlot绘制实时图表。
以下是示例代码:
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "UdpServer.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_connectBtn_clicked(); //点击连接按钮
void updateData(const QByteArray &data); //处理接收到的数据并显示
private:
Ui::MainWindow *ui;
UdpServer *m_udpServer; //udp通信类指针
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include "qcustomplot/qcustomplot.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_udpServer = new UdpServer; //创建udp通信对象
connect(m_udpServer, &UdpServer::dataReceived, this, &MainWindow::updateData); //连接数据接收信号
//初始化QCustomPlot
ui->customPlot->addGraph();
ui->customPlot->xAxis->setLabel("X");
ui->customPlot->yAxis->setLabel("Y");
ui->customPlot->xAxis->setRange(0, 10);
ui->customPlot->yAxis->setRange(0, 10);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_connectBtn_clicked()
{
if(m_udpServer && m_udpServer->bind()) //如果udp通信绑定成功
this->show(); //显示主界面
else
QMessageBox::warning(this, "Warning", "UDP connect failed!"); //提示未成功连接
}
void MainWindow::updateData(const QByteArray &data)
{
qDebug() << "Data received:" << data;
static QTime time(QTime::currentTime());
double key = time.elapsed()/1000.0;
static double lastPointKey = 0;
if(key-lastPointKey > 0.002) //时间间隔大于2ms才更新图表,避免卡顿
{
lastPointKey = key;
double value1 = qSin(key*3.1415926535)+qrand()*0.01/RAND_MAX; //生成测试用的实时数据
double value2 = qCos(key*3.1415926535)+qrand()*0.01/RAND_MAX;
ui->customPlot->graph(0)->addData(key, value1);
ui->customPlot->graph(1)->addData(key, value2);
ui->customPlot->rescaleAxes();
ui->customPlot->replot();
}
}
UdpServer.h
#ifndef UDPSERVER_H
#define UDPSERVER_H
#include <QObject>
#include <QUdpSocket>
class UdpServer : public QObject
{
Q_OBJECT
public:
explicit UdpServer(QObject *parent = nullptr);
bool bind(); //绑定udp通信端口函数
signals:
void dataReceived(const QByteArray &data); //数据接收信号
private slots:
void readPendingDatagrams(); //读取udp数据槽函数
private:
QUdpSocket m_udpSocket; //udp通信类对象
};
#endif // UDPSERVER_H
UdpServer.cpp
#include "UdpServer.h"
#include <QDebug>
UdpServer::UdpServer(QObject *parent) : QObject(parent)
{
}
bool UdpServer::bind()
{
if(m_udpSocket.bind(QHostAddress::Any, 1234)) //绑定udp通信端口
{
connect(&m_udpSocket, &QUdpSocket::readyRead, this, &UdpServer::readPendingDatagrams); //连接数据读取信号
return true;
}
else
return false;
}
void UdpServer::readPendingDatagrams()
{
while (m_udpSocket.hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(m_udpSocket.pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
m_udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
emit dataReceived(datagram); //发送数据接收信号,将数据传递给主界面处理并显示
}
}