chart_file.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. #include "chart_file.h"
  2. #include "ui_chart_file.h"
  3. #include <QDebug>
  4. #include <QMessageBox>
  5. #include <QFile>
  6. chart_file::chart_file(QWidget *parent) :
  7. QWidget(parent),
  8. ui(new Ui::chart_file),
  9. chart(new QChart),
  10. timer(new QTimer),
  11. count(0)
  12. {
  13. ui->setupUi(this);
  14. QStandardItemModel* model = treeModel->tree_set();
  15. ui->tree_set->setModel(model);
  16. ui->tree_set->expandAll();
  17. // 将 QTreeView 的 clicked 信号连接到 handleTreeItemClicked 槽函数
  18. connect(ui->tree_set, &QTreeView::clicked, this, &chart_file::handleTreeItemClicked);
  19. // 初始化变量
  20. time=nullptr;
  21. point1=nullptr;
  22. point2=nullptr;
  23. // 设置点的数量
  24. pointsSize=200;
  25. // 初始化字体颜色
  26. initFontColor();
  27. // 初始化读取数据
  28. initReadData();
  29. // 设置定时器间隔为100毫秒
  30. timer->setInterval(100);
  31. // 启动定时器
  32. timer->start();
  33. }
  34. chart_file::~chart_file()
  35. {
  36. // 释放UI对象和动态分配的内存
  37. delete ui;
  38. // 释放动态分配的数组内存
  39. delete [] time;
  40. delete [] point1;
  41. delete [] point2;
  42. // 释放二维数组tempDis的内存
  43. for (int i=0;i<pointsNum;i++) {
  44. delete [] tempDis[i];
  45. }
  46. delete [] tempDis;
  47. }
  48. void chart_file::setTreeModel(tree_model_set* model)
  49. {
  50. treeModel = model; // 设置 tree_model_set 实例
  51. }
  52. void chart_file::handleTreeItemClicked(const QModelIndex &index) {
  53. // 转发信号
  54. emit treeItemClicked(index);
  55. }
  56. // 鼠标滚轮事件处理函数
  57. void chart_file::wheelEvent(QWheelEvent *event)
  58. {
  59. if (event->angleDelta().y() > 0) {
  60. chart->zoom(1.1);
  61. } else {
  62. chart->zoom(10/1.1);
  63. }
  64. QWidget::wheelEvent(event);
  65. }
  66. void chart_file::initUI()
  67. {
  68. initChart();
  69. }
  70. // 初始化图表
  71. void chart_file::initChart()
  72. {
  73. //chart->createDefaultAxes();
  74. /**修改**/
  75. axisX=new QValueAxis();
  76. axisX->setTitleFont(QFont("Microsoft YaHei", 10, QFont::Normal, true));
  77. axisX->setTitleText("Time(s)");
  78. axisX->setGridLineVisible(true);
  79. chart->addAxis(axisX,Qt::AlignBottom);
  80. axisY=new QValueAxis();
  81. axisY->setTitleFont(QFont("Microsoft YaHei", 10, QFont::Normal, true));
  82. axisY->setTitleText("值");
  83. axisY->setGridLineVisible(true);
  84. chart->addAxis(axisY,Qt::AlignLeft);
  85. for (int i=0;i<pointsNum;i++) {
  86. series[i]->attachAxis(axisX);
  87. series[i]->attachAxis(axisY);
  88. }
  89. /**修改**/
  90. chart->legend()->hide();
  91. chartView = new QChartView(chart);
  92. chartView->setRenderHint(QPainter::Antialiasing);//抗锯齿渲染
  93. ui->mainvertical->addWidget(chartView);
  94. }
  95. // 初始化信号槽连接
  96. // 初始化槽函数,连接信号和槽
  97. void chart_file::initSlot()
  98. {
  99. connect(timer, SIGNAL(timeout()), this, SLOT(timerSlot()));
  100. connect(ui->allRadioButton,SIGNAL(clicked()),this,SLOT(selectAll()));
  101. connect(ui->invertRadioButton,SIGNAL(clicked()),this,SLOT(invertSelect()));
  102. for (int i=0;i<pointsNum;i++) {
  103. connect(checkBoxVector.at(i),SIGNAL(toggled(bool)),this,SLOT(checkboxChanged()));
  104. connect(series[i], SIGNAL(hovered(QPointF, bool)), this, SLOT(tipSlot(QPointF,bool)));
  105. }
  106. }
  107. // 添加图表数据
  108. void chart_file::addChartData(float time, float *pointsDis)
  109. {
  110. float globalMinX = time;
  111. float globalMaxX = time;
  112. float globalMinY = pointsDis[0];
  113. float globalMaxY = pointsDis[0];
  114. for (int i = 0; i < pointsNum; i++)
  115. {
  116. QVector<QPointF> data = series[i]->pointsVector();
  117. data.append(QPointF(time, pointsDis[i]));
  118. float minX = data.at(0).x();
  119. float maxX = data.at(0).x();
  120. float minY = data.at(0).y();
  121. float maxY = data.at(0).y();
  122. for (int j = 0; j < data.size(); j++) {
  123. if (minY > data.at(j).y())
  124. minY = data.at(j).y();
  125. if (maxY < data.at(j).y())
  126. maxY = data.at(j).y();
  127. }
  128. if (i == 0)
  129. {
  130. for (int j = 0; j < data.size(); j++) {
  131. if (minX > data.at(j).x())
  132. minX = data.at(j).x();
  133. if (maxX < data.at(j).x())
  134. maxX = data.at(j).x();
  135. }
  136. globalMinX = minX;
  137. globalMaxX = maxX;
  138. }
  139. globalMinY = globalMinY < minY ? globalMinY : minY;
  140. globalMaxY = globalMaxY > maxY ? globalMaxY : maxY;
  141. series[i]->replace(data);
  142. tempDis[i][0] = pointsDis[i];
  143. tempDis[i][1] = maxY;
  144. tempDis[i][2] = minY;
  145. }
  146. addTableData(tempDis);
  147. axisX->setRange(globalMinX, globalMaxX);
  148. axisY->setRange(globalMinY - (globalMaxY - globalMinY) * 0.1, globalMaxY + (globalMaxY - globalMinY) * 0.1);
  149. }
  150. // 设置点的数量
  151. void chart_file::setPointsNum(int num)
  152. {
  153. if(num>9)
  154. {
  155. QMessageBox::information(this,"Warnning","The number of points exceed 9!");
  156. return;
  157. }
  158. tempDis=new float*[num];
  159. pointsNum=num;
  160. //model->setRowCount(num);
  161. // 该函数用于初始化图表中的数据系列,并为每个数据系列设置颜色和临时数据存储空间
  162. // 参数:
  163. // - pointsNum: 数据系列的数量
  164. // - series: 指向数据系列数组的指针
  165. // - colorTable: 包含每个数据系列颜色的QList
  166. // - chart: 指向图表对象的指针
  167. // - tempDis: 指向临时数据存储数组的指针
  168. for (int i=0;i<pointsNum;i++) {
  169. series[i]=new QLineSeries();
  170. series[i]->setColor(colorTable.at(i));
  171. chart->addSeries(series[i]);
  172. tempDis[i]=new float[3];
  173. }
  174. initUI();
  175. initTable(num);
  176. initSlot();
  177. }
  178. // 添加表格数据
  179. void chart_file::addTableData(float **pointsDis)
  180. {
  181. for (int i=0;i<pointsNum;i++) {
  182. for (int j=0;j<3;j++) {
  183. model->setItem(i, j+1, new QStandardItem(QString::number(pointsDis[i][j])));
  184. model->item(i,j+1)->setForeground(QBrush(colorTable.at(i)));
  185. model->item(i, j+1)->setTextAlignment(Qt::AlignCenter);
  186. }
  187. }
  188. }
  189. // 初始化表格
  190. void chart_file::initTable(int pointsNumber)
  191. {
  192. ui->allRadioButton->setChecked(true);
  193. model = new QStandardItemModel();
  194. model->setColumnCount(4);
  195. model->setHorizontalHeaderItem(0, new QStandardItem(QObject::tr("曲线编号")));
  196. model->setHorizontalHeaderItem(1, new QStandardItem(QObject::tr("Displacements(mm)")));
  197. model->setHorizontalHeaderItem(2, new QStandardItem(QObject::tr("Peak(mm)")));
  198. model->setHorizontalHeaderItem(3, new QStandardItem(QObject::tr("Valley(mm)")));
  199. ui->tableView->setModel(model);
  200. ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
  201. ui->tableView->verticalHeader()->hide();
  202. ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
  203. ui->tableView->setColumnWidth(1,100);
  204. model->setRowCount(pointsNumber);
  205. // 此函数用于在表格视图中创建多个复选框,并将它们添加到模型中
  206. // 每个复选框的标签为 "Point" 加上序号,并根据颜色数组设置样式
  207. // 最后,将复选框添加到表格视图中,并设置其初始状态为选中
  208. QString str="";
  209. for (int i=0;i<pointsNumber;i++) {
  210. str="Point";
  211. str+=QString::number(i+1);
  212. QCheckBox *box=new QCheckBox(str,ui->tableView);
  213. box->setStyleSheet(strColor[i]);
  214. checkBoxVector.append(box);
  215. model->setItem(i, 0, new QStandardItem(""));
  216. ui->tableView->setIndexWidget(model->index(i,0),checkBoxVector.at(i));
  217. model->item(i, 0)->setTextAlignment(Qt::AlignCenter);
  218. checkBoxVector.at(i)->setChecked(true);
  219. }
  220. }
  221. // 全选所有点
  222. void chart_file::selectAll()
  223. {
  224. for(int i=0;i<checkBoxVector.size();i++)
  225. checkBoxVector.at(i)->setChecked(true);
  226. }
  227. // 初始化字体颜色
  228. void chart_file::initFontColor()
  229. {
  230. colorTable.append(QColor(255,0,0));//red
  231. colorTable.append(QColor(0,0,255));//blue
  232. colorTable.append(QColor(0,255,0));//green
  233. colorTable.append(QColor(139,0,0));//dark red
  234. colorTable.append(QColor(255,255,0));//yellow
  235. colorTable.append(QColor(0,0,0));//black
  236. colorTable.append(QColor(128,42,42));//棕色
  237. colorTable.append(QColor(160,32,240));//purple
  238. colorTable.append(QColor(0,255,255));//青色
  239. strColor[0]="QCheckBox{color:rgb(255,0,0)}";
  240. strColor[1]="QCheckBox{color:rgb(0,0,255)}";
  241. strColor[2]="QCheckBox{color:rgb(0,255,0)}";
  242. strColor[3]="QCheckBox{color:rgb(139,0,0)}";
  243. strColor[4]="QCheckBox{color:rgb(255,255,0)}";
  244. strColor[5]="QCheckBox{color:rgb(128,42,42)}";
  245. strColor[7]="QCheckBox{color:rgb(160,32,240)}";
  246. strColor[8]="QCheckBox{color:rgb(0,255,255)}";
  247. }
  248. // 反选所有点
  249. void chart_file::invertSelect()
  250. {
  251. for(int i=0;i<checkBoxVector.size();i++){
  252. if(checkBoxVector.at(i)->checkState())
  253. checkBoxVector.at(i)->setChecked(false);
  254. else
  255. checkBoxVector.at(i)->setChecked(true);
  256. }
  257. }
  258. // 复选框状态改变处理函数
  259. void chart_file::checkboxChanged()
  260. {
  261. for (int i=0;i<pointsNum;i++) {
  262. if(checkBoxVector.at(i)->checkState()){
  263. series[i]->setVisible(true);
  264. }
  265. else {
  266. series[i]->setVisible(false);
  267. }
  268. }
  269. }
  270. // 初始化读取数据
  271. void chart_file::initReadData()
  272. {
  273. QString name = "D:/document/code_all/Qt/QtChartWidget-master/QtChartWidget/data/3.txt";
  274. QFile readFile(name);
  275. int i=0;
  276. if(!readFile.open(QIODevice::ReadOnly | QIODevice::Text))
  277. {
  278. QMessageBox::information(nullptr, "Warning", "Fail to read the file");
  279. return;
  280. }
  281. QTextStream readStream(&readFile);
  282. QString line;
  283. time=new float[10000];
  284. point1=new float[10000];
  285. point2= new float[10000];
  286. QString str="";
  287. while(i<10000)
  288. {
  289. line=readStream.readLine();
  290. if(!line.isEmpty())
  291. {
  292. QStringList list = line.split(QRegularExpression(","), Qt::SkipEmptyParts);
  293. time[i]=list.at(0).toFloat();
  294. point1[i]=list.at(1).toFloat();
  295. point2[i]=list.at(2).toFloat();
  296. if(i<20)
  297. {
  298. str+=QString::number(time[i]);
  299. str+=", ";
  300. str+=QString::number(point1[i]);
  301. str+=", ";
  302. str+=QString::number(point2[i]);
  303. str+="\n";
  304. }
  305. }
  306. i++;
  307. }
  308. readFile.close();
  309. }
  310. // 添加数据
  311. void chart_file::addData()
  312. {
  313. float y[2];
  314. y[0]=point1[count];
  315. y[1]=point2[count];
  316. addChartData(time[count],y);
  317. count++;
  318. }
  319. // 定时器槽函数
  320. void chart_file::timerSlot()
  321. {
  322. if (QObject::sender() == timer) {
  323. addData();
  324. }
  325. }