图像界面上位机软件
上位机软件功能
本人设计的上位机主要分为信号图像显示区、按键和参数设置区和文字信息区三大部分。 整个上位机软件主要分为三部分: 1. 启动和关闭 Geant4 物理仿真软件并且设置相关参数。 2. 显示探测器能量沉积数字信号。 3. 显示 TCP连接状态信息和 Geant 4 探测器能量沉积。
但是有一点我很不理解,为了实现每次接收到TCP数据帧,都能够更新信号图像,我把new空间放到了header文件中,在cpp文件的doProcessNewConnect函数中怎么都没有办法实现。本人觉得这是不好的编程习惯但是也是无奈之举。。。如果你知道欢迎回复!
mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void begin_G4();
void Qt_Tcp();
void receive();
void doProcessNewConnect(QByteArray);
DataTable generateRandomData(int listCount, int valueMax, int valueCount) const;
QTcpServer *TcpServer;
QTcpSocket *TcpSocket;
QChart *chart = new QChart();
QLineSeries *series2 = new QLineSeries(chart); //初始化一条折线 chart
QChartView *chartView = new QChartView(chart);
QVBoxLayout * pre;
QByteArray array1;
QProcess *poc;
QByteArray output1;
QString str_output1;
void on_readoutput();
private slots:
void on_pushButton_close_clicked();
private:
Ui::MainWindow *ui;
};
mianwindows.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->spinBox->setValue(1);
ui->spinBox_2->setValue(1);
//TCP Server
//指定父对象,让其自动回收空间
TcpServer = NULL;
TcpSocket = NULL;
TcpServer = new QTcpServer();
TcpServer->listen(QHostAddress::Any, 8000);
if(!TcpServer)//服务器打开失败
{
ui->textEdit->append("cannot open the TCP server!");//追加显示
ui->textEdit->append("\n");
return;
}
setWindowTitle("server port : 8000");
connect(TcpServer, &QTcpServer::newConnection,
this, &MainWindow::receive);
connect(ui->pushButton_begin, &QPushButton::pressed, this, &MainWindow::begin_G4);
//ui->pushButton信号发出者,&QPushButton::pressed 处理信号,发送者的类名::信号名字
//this 信号接受者
//&MainWindow::begin_G4槽函数,信号处理函数 接受者类名::槽函数名字
connect(poc, &QProcess::readyReadStandardOutput,
this, &MainWindow::on_readoutput);
}
void MainWindow::receive()
{
//取出建立好连接的套接字
TcpSocket = TcpServer->nextPendingConnection();
QString ip = TcpSocket->peerAddress().toString();
qint16 port1 = TcpSocket->peerPort();
QString port2 = QString::number(port1);
ui->textEdit->append("Tcp client address :");
ui->textEdit->append(ip);
ui->textEdit->append("\n");
ui->textEdit->append("Tcp client port :");
ui->textEdit->append(port2);
ui->textEdit->append("\n");
connect(TcpSocket, &QTcpSocket::readyRead, this,
&MainWindow::read_data);
}
void MainWindow::read_data()
{
array_read_data = TcpSocket->readAll();
doProcessNewConnect(array_read_data);
array_read_data.clear();
}
void MainWindow::doProcessNewConnect(QByteArray array1)
{
QList<QPointF> Data2;
QPointF point1;
//int nameIndex = 0;
int number1 = 0; //读取出TCP帧中传输的数据量
for(int ii=0;ii<3;ii++)
{ //把ASII码转换为int类型
number1 += (array1[ii]-48) * qPow(10, 2-ii);
}
int gg=3;
int sequence = 9;
ui->textEdit->append("energy deposition :");
for(int nn=0; nn<number1; nn++)
{
QByteArray array3;
float number4 = 0.0;
int number3[3];
for(int mm=0; mm<3; mm++)
{
number3[mm] = array1[gg+mm] - 48;
number4 += (array1[gg+mm] - 48) * qPow(10, -mm);
qDebug()<<"number4 = "<<number4;
QString data = QString("float is %1").arg(number4);
ui->textEdit->append(data);
}
qDebug()<<"QByteArray number3 : "
<<number3[0]
<<number3[1]
<<number3[2];
//qDebug()<<"number4="<<number4;
point1.setX(sequence);
point1.setY(number4);
Data2.append(point1);
if(nn%5==0) sequence += 6;
else if(nn%5==1) sequence +=5;
else if(nn%5==2) sequence +=7;
else if(nn%5==3) sequence +=6;
else if(nn%5==4) sequence +=5;
gg +=3;
}
chart->addSeries(series2);//chart中添加一条折线
QString name("energy deposition ");
series2->setName(name);//折线设置名字
series2->replace(Data2);
chart->createDefaultAxes();// 创建坐标
chart->axes(Qt::Vertical).first()->setRange(0, 10);//设置纵坐标范围
// Add space to label to add space between labels and axis
QValueAxis *axisY = qobject_cast<QValueAxis*>(chart->axes(Qt::Vertical).first());
//利用qobject_cast进行安全转换,将QAbstractAxis类型的变量转换为QVasequencelueAxis,为的是在下面使用->setLabelFormat("%.1f ")
Q_ASSERT(axisY);//当axisY == 0时,程序会中断
axisY->setLabelFormat("%.2f ");//设置坐标的值精确到小数点后2位
//chart->legend()->hide();//隐藏图例
chart->legend()->setAlignment(Qt::AlignTop);//设置图例位置在顶部
chart->setAnimationOptions(QChart::GridAxisAnimations);//设置动画效果,在第一次显示图表或者更改图标区域大小的时候会显示动画效果
chart->axes(Qt::Horizontal).first()->setRange(0, sequence);//设置横坐标范围
//ui->widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pre = ui->verticalLayout; //new QVBoxLayout(ui->widget)
pre->addWidget(chartView);
}
void MainWindow::begin_G4()
{
//spinbox
QString detector_number;
ui->spinBox->setValue(55);
ui->spinBox->setRange(1, 100);
ui->spinBox->setSingleStep(1);
ui->spinBox->setWrapping(true);
//get the number
detector_number = ui->spinBox->text();
//spinbox
QString emitted_particle;
ui->spinBox_2->setRange(1, 10000);
ui->spinBox_2->setSingleStep(1);
ui->spinBox_2->setWrapping(true);
//get the number
emitted_particle = ui->spinBox_2->text();
//新建run_mao.mac文件,并且执行,每次对文件覆盖之后重新写入
QFile file("/home/zx/maojunjie/NeutronSource/build/run_mao.mac");
//(/home/zx/maojunjie/NeutronSource/build/run_mao.mac, D:/run_mao.mac)
file.open(QIODevice::WriteOnly | QIODevice::Text);
QString a1 = "/control/verbose 2\r\n";
file.write(a1.toUtf8());
QString a2 = "/run/verbose 1\r\n";
file.write(a2.toUtf8());
QString a3 = "/testhadr/stepping/seDSN " + detector_number + "\r\n";
file.write(a3.toUtf8());
QString a4 = "/run/initialize\r\n";
file.write(a4.toUtf8());
QString a5 = "/process/list\r\n";
file.write(a5.toUtf8());
QString a6 = "/gun/particle ion\r\n";
file.write(a6.toUtf8());
QString a7 = "/gun/ion 95 241\r\n";
file.write(a7.toUtf8());
QString a8 = "/gun/energy 0. eV\r\n";
file.write(a8.toUtf8());
QString a9 = "/run/printProgress " + emitted_particle + "\r\n";
file.write(a9.toUtf8());
QString a10 = "/run/beamOn " + emitted_particle + "\r\n";
file.write(a10.toUtf8());
file.close();
//启动bash命令,写入命令并且执行,启动Geant 4物理仿真软件
poc->start("bash");
poc->waitForFinished();
poc->write("source /home/zx/Main_Install/geant4.10.05.p01-install/bin/geant4.sh\n");
poc->waitForFinished();
poc->write("cd /home/zx/maojunjie/NeutronSource/build\n");
poc->write("./NeutronSource run_mao.mac\n");
}
//读取运行bash的信息
void MainWindow::on_readoutput()
{
ui->textEdit->append(poc->readAllStandardOutput().data());
}