chart_file.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  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. for (int i=0;i<pointsNum;i++)
  109. {
  110. QVector<QPointF> oldData = series[i]->pointsVector();
  111. QVector<QPointF> data;
  112. if(oldData.size()<pointsSize){
  113. data=oldData;
  114. }
  115. else {
  116. oldData.removeFirst();
  117. data=oldData;
  118. }
  119. }
  120. */
  121. // 添加图表数据
  122. void chart_file::addChartData(float time, float *pointsDis)
  123. {
  124. float globalMinX = 0;
  125. float globalMaxX = time;
  126. float globalMinY = pointsDis[0];
  127. float globalMaxY = pointsDis[0];
  128. for (int i = 0; i < pointsNum; i++)
  129. {
  130. // 获取第 i 个数据系列的点向量
  131. QVector<QPointF> data = series[i]->pointsVector();
  132. data.append(QPointF(time, pointsDis[i]));
  133. float minX = data.at(0).x();
  134. float maxX = data.at(0).x();
  135. float minY = data.at(0).y();
  136. float maxY = data.at(0).y();
  137. for (int j = 0; j < data.size(); j++) {
  138. if (minY > data.at(j).y())
  139. minY = data.at(j).y();
  140. if (maxY < data.at(j).y())
  141. maxY = data.at(j).y();
  142. }
  143. if (i == 0)
  144. {
  145. for (int j = 0; j < data.size(); j++) {
  146. if (maxX < data.at(j).x())
  147. maxX = data.at(j).x();
  148. }
  149. globalMaxX = maxX;
  150. }
  151. globalMinY = globalMinY < minY ? globalMinY : minY;
  152. globalMaxY = globalMaxY > maxY ? globalMaxY : maxY;
  153. series[i]->replace(data);
  154. tempDis[i][0] = pointsDis[i];
  155. tempDis[i][1] = maxY;
  156. tempDis[i][2] = minY;
  157. }
  158. addTableData(tempDis);
  159. axisX->setRange(globalMinX, globalMaxX);
  160. axisY->setRange(globalMinY - (globalMaxY - globalMinY) * 0.1, globalMaxY + (globalMaxY - globalMinY) * 0.1);
  161. }
  162. // 设置点的数量
  163. void chart_file::setPointsNum(int num)
  164. {
  165. if(num>9)
  166. {
  167. QMessageBox::information(this,"Warnning","The number of points exceed 9!");
  168. return;
  169. }
  170. tempDis=new float*[num];
  171. pointsNum=num;
  172. //model->setRowCount(num);
  173. // 该函数用于初始化图表中的数据系列,并为每个数据系列设置颜色和临时数据存储空间
  174. // 参数:
  175. // - pointsNum: 数据系列的数量
  176. // - series: 指向数据系列数组的指针
  177. // - colorTable: 包含每个数据系列颜色的QList
  178. // - chart: 指向图表对象的指针
  179. // - tempDis: 指向临时数据存储数组的指针
  180. for (int i=0;i<pointsNum;i++) {
  181. series[i]=new QLineSeries();
  182. series[i]->setColor(colorTable.at(i));
  183. chart->addSeries(series[i]);
  184. tempDis[i]=new float[3];
  185. }
  186. initUI();
  187. initTable(num);
  188. initSlot();
  189. }
  190. // 添加表格数据
  191. void chart_file::addTableData(float **pointsDis)
  192. {
  193. for (int i=0;i<pointsNum;i++) {
  194. for (int j=0;j<1;j++) {
  195. model->setItem(i, j+1, new QStandardItem(QString::number(pointsDis[i][j])));
  196. model->item(i,j+1)->setForeground(QBrush(colorTable.at(i)));
  197. model->item(i, j+1)->setTextAlignment(Qt::AlignCenter);
  198. }
  199. }
  200. }
  201. // 初始化表格
  202. void chart_file::initTable(int pointsNumber)
  203. {
  204. ui->allRadioButton->setChecked(true);
  205. model = new QStandardItemModel();
  206. model->setColumnCount(2);
  207. model->setHorizontalHeaderItem(0, new QStandardItem(QObject::tr("曲线编号")));
  208. model->setHorizontalHeaderItem(1, new QStandardItem(QObject::tr("当前值")));
  209. // model->setHorizontalHeaderItem(2, new QStandardItem(QObject::tr("Peak(mm)")));
  210. // model->setHorizontalHeaderItem(3, new QStandardItem(QObject::tr("Valley(mm)")));
  211. ui->tableView->setModel(model);
  212. ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
  213. ui->tableView->verticalHeader()->hide();
  214. ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
  215. ui->tableView->setColumnWidth(1,100);
  216. model->setRowCount(pointsNumber);
  217. // 此函数用于在表格视图中创建多个复选框,并将它们添加到模型中
  218. // 每个复选框的标签为 "Point" 加上序号,并根据颜色数组设置样式
  219. // 最后,将复选框添加到表格视图中,并设置其初始状态为选中
  220. QString str="";
  221. for (int i=0;i<pointsNumber;i++) {
  222. str="Point";
  223. str+=QString::number(i+1);
  224. QCheckBox *box=new QCheckBox(str,ui->tableView);
  225. box->setStyleSheet(strColor[i]);
  226. checkBoxVector.append(box);
  227. model->setItem(i, 0, new QStandardItem(""));
  228. ui->tableView->setIndexWidget(model->index(i,0),checkBoxVector.at(i));
  229. model->item(i, 0)->setTextAlignment(Qt::AlignCenter);
  230. checkBoxVector.at(i)->setChecked(true);
  231. }
  232. }
  233. // 全选所有点
  234. void chart_file::selectAll()
  235. {
  236. for(int i=0;i<checkBoxVector.size();i++)
  237. checkBoxVector.at(i)->setChecked(true);
  238. }
  239. // 初始化字体颜色
  240. void chart_file::initFontColor()
  241. {
  242. colorTable.append(QColor(255,0,0));//red
  243. colorTable.append(QColor(0,0,255));//blue
  244. colorTable.append(QColor(0,255,0));//green
  245. colorTable.append(QColor(139,0,0));//dark red
  246. colorTable.append(QColor(255,255,0));//yellow
  247. colorTable.append(QColor(0,0,0));//black
  248. colorTable.append(QColor(128,42,42));//棕色
  249. colorTable.append(QColor(160,32,240));//purple
  250. colorTable.append(QColor(0,255,255));//青色
  251. strColor[0]="QCheckBox{color:rgb(255,0,0)}";
  252. strColor[1]="QCheckBox{color:rgb(0,0,255)}";
  253. strColor[2]="QCheckBox{color:rgb(0,255,0)}";
  254. strColor[3]="QCheckBox{color:rgb(139,0,0)}";
  255. strColor[4]="QCheckBox{color:rgb(255,255,0)}";
  256. strColor[5]="QCheckBox{color:rgb(128,42,42)}";
  257. strColor[7]="QCheckBox{color:rgb(160,32,240)}";
  258. strColor[8]="QCheckBox{color:rgb(0,255,255)}";
  259. }
  260. // 反选所有点
  261. void chart_file::invertSelect()
  262. {
  263. for(int i=0;i<checkBoxVector.size();i++){
  264. if(checkBoxVector.at(i)->checkState())
  265. checkBoxVector.at(i)->setChecked(false);
  266. else
  267. checkBoxVector.at(i)->setChecked(true);
  268. }
  269. }
  270. // 复选框状态改变处理函数
  271. void chart_file::checkboxChanged()
  272. {
  273. for (int i=0;i<pointsNum;i++) {
  274. if(checkBoxVector.at(i)->checkState()){
  275. series[i]->setVisible(true);
  276. }
  277. else {
  278. series[i]->setVisible(false);
  279. }
  280. }
  281. }
  282. // 初始化读取数据
  283. void chart_file::initReadData()
  284. {
  285. QString name = "D:/document/code_all/Qt/QtChartWidget-master/QtChartWidget/data/3.txt";
  286. QFile readFile(name);
  287. int i=0;
  288. if(!readFile.open(QIODevice::ReadOnly | QIODevice::Text))
  289. {
  290. QMessageBox::information(nullptr, "Warning", "Fail to read the file");
  291. return;
  292. }
  293. QTextStream readStream(&readFile);
  294. QString line;
  295. time=new float[10000];
  296. point1=new float[10000];
  297. point2= new float[10000];
  298. QString str="";
  299. while(i<10000)
  300. {
  301. line=readStream.readLine();
  302. if(!line.isEmpty())
  303. {
  304. QStringList list = line.split(QRegularExpression(","), Qt::SkipEmptyParts);
  305. time[i]=list.at(0).toFloat();
  306. point1[i]=list.at(1).toFloat();
  307. point2[i]=list.at(2).toFloat();
  308. if(i<20)
  309. {
  310. str+=QString::number(time[i]);
  311. str+=", ";
  312. str+=QString::number(point1[i]);
  313. str+=", ";
  314. str+=QString::number(point2[i]);
  315. str+="\n";
  316. }
  317. }
  318. i++;
  319. }
  320. readFile.close();
  321. }
  322. // 添加数据
  323. void chart_file::addData()
  324. {
  325. float y[2];
  326. y[0]=point1[count];
  327. y[1]=point2[count];
  328. addChartData(time[count],y);
  329. count++;
  330. }
  331. // 定时器槽函数
  332. void chart_file::timerSlot()
  333. {
  334. if (QObject::sender() == timer) {
  335. addData();
  336. }
  337. }
  338. void chart_file::on_btn_clear_clicked()
  339. {
  340. timer->stop(); // 停止定时器
  341. for (int i = 0; i < pointsNum; i++)
  342. {
  343. series[i]->clear();
  344. }
  345. count = 0; // 重置计数
  346. chart->update();
  347. chartView->repaint();
  348. timer->start(); // 重新启动定时器(如果需要)
  349. }
  350. void chart_file::on_btn_save_clicked()
  351. {
  352. for (int i=0;i<pointsNum;i++)
  353. {
  354. series[i]->clear();
  355. }
  356. }