标签(空格分隔): QT 、Socket 、UE4
//COPYRIGHT NOTICE //Copyright (c) 2018, 四川xx科技有限公司 (版权声明) //2018,xx科技 UE4组 Lp 修改 //All rights reserved.
该项目为中铁客户端(QT部分),采用QT5.7X64编译,适用于windows server 2016及以上系统。该项目主要包括:数据可视化、Socket通讯、内嵌ue4可执行程序三大方面
数据可视化即采用图形图表等第三方库对采集的数据进行动态展示,可以非常直观的查看传感器采集到的数据。这部分主要采用了两大图形图标库:QT自带的库:QtCharts和第三方库:QCustomPlot。
QtCharts由于是qt自带的使用也是比较广泛的图形展示库,本项目中将它封装在statisticalwindow类中。我们在使用它时应该注意三点
①在.pro文件中添加:
QT += charts;
②添加自己需要的头文件:
#include#include #include //根据需要自行添加
③在代码前声明命名空间:
using namespace QtCharts;
示例代码:
void StatisticalWindow::Creatpie_chart() { //构建QPieSeries作为饼图为其添加3个切片QPieSlice数据源 QPieSeries *pieSeries = new QPieSeries(); //设置中心圆大小 pieSeries->setHoleSize(0.35); //添加数据 QPieSlice *slice1=pieSeries->append(QString::fromLocal8Bit("正常个数92个"), 40); slice1->setColor(QColor(0,226,255,150));//设置背景颜色 slice1->setLabelColor(QColor(0,226,255,255));//标签颜色 slice1->setBorderColor(QColor(255,58,93,90));//边框颜色 slice1->setLabelVisible(true);//设置标签可见 QPieSlice *slice2=pieSeries->append(QString::fromLocal8Bit("异常个数6个"), 6); slice2->setLabelColor(QColor(0,226,255,255)); slice2->setColor(QColor(0,226,255,220)); slice2->setBorderColor(QColor(255,58,93,90));//边框颜色 slice2->setLabelVisible(true); QPieSlice *slice3 = pieSeries->append(QString::fromLocal8Bit("危险个数4个"), 4); //slice3->setExploded();//炸开 slice3->setLabelVisible(true); slice3->setLabelColor(QColor(0,226,255,255)); slice3->setBorderColor(QColor(255,58,93,90));//边框颜色 slice3->setColor(QColor(255,58,93,230)); QChart *pieChart = new QChart(); pieChart->addSeries(pieSeries); // 将 series 添加至图表 pieChart->setTitle(QString::fromLocal8Bit("所有监测点数据统计")); pieChart->setTitleFont(QFont(QString::fromLocal8Bit("所有监测点数据统计"),11));//字体大小 pieChart->setTitleBrush(QBrush(QColor(255,255,255,200))); //pieChart->setGeometry(0,400,400,400); pieChart->legend()->setAlignment(Qt::AlignBottom); //pieChart->setTheme(QChart::ChartThemeBrownSand); QString path1=QDir::currentPath()+"/imgs/1.png";//大表盘背景图 QPixmap pixmap(path1);//设定图片 ui->QchartviewPie_label->setPixmap(pixmap); pieChart->setBackgroundBrush(QBrush(QColor(255,255,255,0)));//设置背景透明 //设置给控件显示(QchartviewPie是ui界面中拖入widget控件并将它提升为Qchartview类) ui->QchartviewPie->setRenderHint(QPainter::Antialiasing); pieChart->setSelected(true); ui->QchartviewPie->setChart(pieChart); }
QCustomPlot是目前QT公认为比较好用的第三方图形展示库,库里就只有qcustomplot.h和qcustomplot.cpp两个主要文件。本项目主要封装于showonepoint类中,以及mainwindow类也有使用。使用各类需要注意:
①:将下载好的QCustomPlot压缩包解压后的qcustomplot.h和qcustomplot.cpp两个文件放到自己项目的.pro同级目录,然后打开项目-添加现有文件,分别将这两个文件添加进自己的项目中。
②:在.pro文件中添加:
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
③:执行qmark
示例代码:
//该函数代码不完整,主要展示图表细节设置代码 void MainWindow::ShowAllType() { //三大类的折线展示图 ui->AllTypeshow->addGraph();//添加线条 ...... //设置线条 ui->AllTypeshow->graph(0)->setName(QString::fromLocal8Bit("风速平均值")); ui->AllTypeshow->graph(0)->setPen(QPen(QColor(0,226,255,180)));//风速线颜色 ui->AllTypeshow->setBackground(QBrush(QColor(27, 27, 27,255)));//背景色 //设置坐标轴名称 //ui->AllTypeshow->yAxis->setSelectedTickLabelColor(QColor(0,226, 255,255));//设置单击选中后的坐标颜色 ui->AllTypeshow->xAxis->setLabel(QString::fromLocal8Bit("各类传感器实时数据"));//x标签 ui->AllTypeshow->xAxis->setLabelColor(QColor(255,255, 255,200));//x标签颜色 ui->AllTypeshow->xAxis->setTickLabelColor(QColor(0,226, 255,255));//x的数据颜色 ui->AllTypeshow->xAxis->setBasePen(QPen(QColor(0,226, 255,255)));//x轴基础线颜色 ui->AllTypeshow->xAxis->setSubTickPen(QPen(QColor(0,226, 255,255)));//x轴小刻度颜色 ui->AllTypeshow->yAxis->setLabelColor(QColor(255,255, 255,200));//Y标签 ui->AllTypeshow->yAxis->setTickLabelColor(QColor(0,226, 255,255)); ui->AllTypeshow->yAxis->setLabel(QString::fromLocal8Bit("实时平均值"));//y标签 ui->AllTypeshow->yAxis->setBasePen(QPen(QColor(0,226, 255,255))); ui->AllTypeshow->yAxis->setSubTickPen(QPen(QColor(0,226, 255,255))); ui->AllTypeshow->xAxis->grid()->setPen(QPen(QColor(0,226, 255,100)));//x栅格颜色 QPen qcustomx_grid_pen;//x轴网格线风格 qcustomx_grid_pen.setColor(QColor(0,226, 255,100)); qcustomx_grid_pen.setStyle(Qt::DotLine); ui->AllTypeshow->xAxis->grid()->setPen(qcustomx_grid_pen); QPen qcustomy_grid_pen;//y轴网格线风格 qcustomy_grid_pen.setColor(QColor(0,226, 255,100)); qcustomy_grid_pen.setStyle(Qt::DotLine); ui->AllTypeshow->yAxis->grid()->setPen(qcustomy_grid_pen); ui->AllTypeshow->xAxis-> setTicks(true); //不显示坐标轴 ui->AllTypeshow->xAxis->setRange(0, 30); ui->AllTypeshow->yAxis->setRange(1, 80); //启用拖拽事件等 ui->AllTypeshow->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables); ui->AllTypeshow->legend->setBrush(QBrush(QColor(0,226,255,100))); ui->AllTypeshow->legend->setVisible(true);//设置图表的标注可见 //添加数据,这里演示y=30-35浮动数据 for (int i = 0; i<30; i++) { X_WD.append(i); // Y_WD.append(qrand()%3+30);//温度数据取值在30-33浮动 Y_FS.append(qrand()%8+3);//风速在3-11浮动(单位:m/s) Y_ZD.append(qrand()%10+50);//震动在50-60浮动(单位%) Y_YL.append(qrand()%10+15);//应力在15-25浮动单位用kgf/mm2 Y_JS.append(qrand()%10+30); } //给三大类实时数据设置数据 ui->AllTypeshow->graph(0)->setData(X_WD, Y_FS); ui->AllTypeshow->graph(1)->setData(X_WD, Y_ZD);//震动 ui->AllTypeshow->graph(2)->setData(X_WD, Y_YL); ui->AllTypeshow->graph(3)->setData(X_WD, Y_JS); }
QT部分的通讯主要涉及到和服务端 、后台通讯以及ue4程序间的通讯,均采用socket通讯来完成:
服务端通讯:主要 是获取传感器数据,通过不停地向服务端发送命令以获取各个传感器的状态以及数据等,解析或计算后用于实施呈现在图形图表之中。
示例代码:
暂无:
内嵌ue4程序通讯:主要是将qt作为服务端,在启动qt时初始化QTcpServer进行监听,然后启动外部ue4程序等待其连接。一ue4发消息qt接消息,qt接收消息并解析后执行响应操作。②qt发ue4程序接:qt不停发送消息以便ue4不间断更新传感器状态等。关于QT中使用socket:
①在.pro中添加、在头文件添加
QT += network #include#include
②初始化监听、新连接、接收消息
//初始化socket进行监听,等待连接 void MainWindow::SocketListen() { server = new QTcpServer(); server->listen(QHostAddress::Any, Port);//监听端口Port(#define Port 9537) connect(server, SIGNAL(newConnection()), this, SLOT(SocketConnect()));//当有一个新连接过来, 执行socketcontent } //新的Socket连接 void MainWindow::SocketConnect() { //初始化thissocket,得到这个连接 thissocket = server->nextPendingConnection(); if(thissocket) { connect(thissocket, SIGNAL(readyRead()), this, SLOT(SocketRecv())); //当接受到消息 } } //接受解析socket消息 void MainWindow::SocketRecv() { if(thissocket->isValid()) { QByteArray arr=thissocket->readAll();//读取消息 QString data = arr;//QString::fromLocal8Bit(arr);将接收得到的unicode字符转为自己的utf8字符集,如果发送的已经转了那就直接接收 if(!data.isEmpty()) { Execute_sockecommand(data);//根据命令执行操作响应 } } }
该部分主要是将外部程序嵌入qt程序中,作为其一个子窗口进行展示。只要是通过qt启动外部程序,然后利用windows函数FindWindow()获得ue4窗口句柄handle,然后就是对这个handle的操作。
目前这个嵌入ue4exe的地方有点问题:一般做法是利用一个QWindow 来作为这个handle的代理,再利用QWidget在显示这个QWindow 已达到QT嵌入外部exe。实际上这种方法对绝大多数应用程序来说都比较实用,但是对于ue4来说却存在焦点问题!尝试许久无果后,无奈之举只能直接对handle进行移动缩放让其跟随qt窗口进行运动。
①移动ue4exe窗口
MoveWindow(hwnWindow,startpoint.x(),startpoint.y(),1041,540,1);
②关闭时自身时结束ue4exe。(结束本应该写在~mainwindow()里面,这里直接截取QCloseEvent事件进行处理)
//关闭操作响应 void MainWindow::closeEvent(QCloseEvent *event) { switch( QMessageBox::information(this,QString::fromLocal8Bit("提示"),QString::fromLocal8Bit("你确定退出该软件"),QString::fromLocal8Bit("确定"),QString::fromLocal8Bit("取消"),0,1)) { case 0: { QString exename="UE4Game.exe"; exename="sensor.exe"; terminateMyexe(exename);//查找并结束exe delete mypie; break; event->accept();//接受关闭消息 } case 1: default: event->ignore();//忽略 break; } }
该版本为为了解决ue4焦点问题而新写的第二版本,经测试比较稳定,没有出现其他问题。