代码拉取完成,页面将自动刷新
同步操作将从 觉皇/QtSerialPortPlotter 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/***************************************************************************
** This file is part of Serial Port Plotter **
** **
** **
** Serial Port Plotter is a program for plotting integer data from **
** serial port using Qt and QCustomPlot **
** **
** This program is free software: you can redistribute it and/or modify **
** it under the terms of the GNU General Public License as published by **
** the Free Software Foundation, either version 3 of the License, or **
** (at your option) any later version. **
** **
** This program is distributed in the hope that it will be useful, **
** but WITHOUT ANY WARRANTY; without even the implied warranty of **
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
** GNU General Public License for more details. **
** **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see http://www.gnu.org/licenses/. **
** **
****************************************************************************
** Author: Borislav **
** Contact: [email protected] **
** Date: 29.12.14 **
****************************************************************************/
#include "mainwindow.hpp"
#include "ui_mainwindow.h"
#include <x86intrin.h>
MainWindow::MainWindow (QWidget *parent) :
QMainWindow (parent),
ui (new Ui::MainWindow)
{
ui->setupUi (this);
createUI();
setupPlot();
serialPort = new QSerialPort(this);
connect (serialPort, SIGNAL(readyRead()), this, SLOT(readData()));
connect (this, SIGNAL(newData(QStringList)), this, SLOT(onNewDataArrived(QStringList)));
connect (this, SIGNAL(newData(QStringList)), this, SLOT(saveStream(QStringList)));
connect(ui->textBrowser, &QTextEdit::textChanged, this, [=](){
ui->textBrowser->moveCursor(QTextCursor::End);
});
connect(ui->hideRecvAreaCheckBox, &QCheckBox::stateChanged, this, [=](int state){
if(state == Qt::Checked)
{
ui->textBrowser->setVisible(false);
}else
{
ui->textBrowser->setVisible(true);
}
});
// connect(ui->hideRecvDataCheckBox, &QCheckBox::stateChanged, this, [=](int state){
// if(state == Qt::Checked)
// {
// ui->hideRecvAreaCheckBox->setChecked(true);
// ui->hideRecvAreaCheckBox->setVisible(false);
// ui->dataFormatCheckBox->setVisible(false);
// }else
// {
// ui->hideRecvAreaCheckBox->setChecked(false);
// ui->hideRecvAreaCheckBox->setVisible(true);
// ui->dataFormatCheckBox->setVisible(true);
// }
// });
}
MainWindow::~MainWindow()
{
on_actionDisconnect_triggered();
delete ui;
}
void MainWindow::closeEvent(QCloseEvent* e)
{
Settings::setPortName(ui->comboPort->currentText());
Settings::setBaudrate(ui->comboBaud->currentText().toInt());
Settings::setDatabits(ui->comboData->currentIndex());
Settings::setStopbits(ui->comboStop->currentIndex());
Settings::setParity(ui->comboParity->currentIndex());
Settings::setTheme(Settings::getTheme());
Settings::setLineColors(Settings::getLineColors());
Settings::setHideRecvArea(ui->hideRecvAreaCheckBox->isChecked());
Settings::setHideRecvData(ui->hideRecvDataCheckBox->isChecked());
Settings::setDisplayRawData(ui->dataFormatCheckBox->isChecked());
Settings::setWindowPos(pos());
Settings::setWindowSize(size());
QList<int> l;
l.append(ui->spinPoints->value());
l.append(ui->spinYStep->value());
l.append(ui->spinAxesMin->value());
l.append(ui->spinAxesMax->value());
Settings::setPlotArgs(l);
QWidget::closeEvent(e);
}
void MainWindow::createUI()
{
for (QSerialPortInfo port : QSerialPortInfo::availablePorts())
{
ui->comboPort->addItem (port.portName());
}
/* Populate baud rate combo box with standard rates */
ui->comboBaud->addItem ("1200");
ui->comboBaud->addItem ("2400");
ui->comboBaud->addItem ("4800");
ui->comboBaud->addItem ("9600");
ui->comboBaud->addItem ("19200");
ui->comboBaud->addItem ("38400");
ui->comboBaud->addItem ("57600");
ui->comboBaud->addItem ("115200");
/* And some not-so-standard */
ui->comboBaud->addItem ("128000");
ui->comboBaud->addItem ("153600");
ui->comboBaud->addItem ("230400");
ui->comboBaud->addItem ("256000");
ui->comboBaud->addItem ("460800");
ui->comboBaud->addItem ("921600");
/* Populate data bits combo box */
ui->comboData->addItem (tr("8位"));
ui->comboData->addItem (tr("7位"));
/* Populate parity combo box */
ui->comboParity->addItem (tr("无校验"));
ui->comboParity->addItem (tr("奇校验"));
ui->comboParity->addItem (tr("偶校验"));
/* Populate stop bits combo box */
ui->comboStop->addItem (tr("1位"));
ui->comboStop->addItem (tr("2位"));
/* Initialize the listwidget */
ui->listWidget_Channels->clear();
ui->comboPort->installEventFilter(this);
ui->textBrowser->document()->setMaximumBlockCount(1000); /* 设置最大显示1000行 */
ui->comboPort->setCurrentIndex(ui->comboPort->findText(Settings::getPortName()));
ui->comboBaud->setCurrentText(QString("%1").arg(Settings::getBaudrate()));
ui->comboData->setCurrentIndex(Settings::getDatabits());
ui->comboStop->setCurrentIndex(Settings::getStopbits());
ui->comboParity->setCurrentIndex(Settings::getParity());
ui->hideRecvAreaCheckBox->setChecked(Settings::hideRecvArea());
ui->hideRecvDataCheckBox->setChecked(Settings::hideRecvData());
ui->dataFormatCheckBox->setChecked(Settings::displayRawData());
lineColorNamesStrList = Settings::getLineNames();
if(ui->hideRecvAreaCheckBox->isChecked())
{
ui->textBrowser->setVisible(false);
}
QList<int> l = Settings::plotArgs();
ui->spinPoints->setValue(l[0]);
ui->spinYStep->setValue(l[1]);
ui->spinAxesMin->setValue(l[2]);
ui->spinAxesMax->setValue(l[3]);
enable_com_controls(true);
resize(Settings::windowSize());
move(Settings::windowPos());
}
void MainWindow::setupPlot()
{
foreach(QString color, Settings::getLineColors())
{
lineColorsList.append(QColor(color));
}
if(Settings::getTheme() == 0)
{
gui_colors[0] = QColor (255, 255, 255, 255); /**< 0: qdark ui dark/background color */
gui_colors[1] = QColor (175, 175, 175, 255); /**< 0: qdark ui dark/background color */
gui_colors[2] = QColor (85, 85, 85, 255); /**< 0: qdark ui dark/background color */
gui_colors[3] = QColor (207, 208, 208, 200); /**< 0: qdark ui dark/background color */
}else
{
gui_colors[0] = QColor (48, 47, 47, 255); /**< 0: qdark ui dark/background color */
gui_colors[1] = QColor (80, 80, 80, 255); /**< 1: qdark ui medium/grid color */
gui_colors[2] = QColor (170, 170, 170, 255); /**< 2: qdark ui light/text color */
gui_colors[3] = QColor (48, 47, 47, 200); /**< 3: qdark ui dark/background color w/transparency */
}
/* Background for the plot area */
ui->plot->setBackground (gui_colors[0]);
/* Used for higher performance (see QCustomPlot real time example) */
ui->plot->setNotAntialiasedElements (QCP::aeAll);
QFont font;
font.setStyleStrategy (QFont::NoAntialias);
ui->plot->legend->setFont (font);
/** See QCustomPlot examples / styled demo **/
/* X Axis: Style */
ui->plot->xAxis->grid()->setPen (QPen(gui_colors[2], 1, Qt::DotLine));
ui->plot->xAxis->grid()->setSubGridPen (QPen(gui_colors[1], 1, Qt::DotLine));
ui->plot->xAxis->grid()->setSubGridVisible (true);
ui->plot->xAxis->setBasePen (QPen (gui_colors[2]));
ui->plot->xAxis->setTickPen (QPen (gui_colors[2]));
ui->plot->xAxis->setSubTickPen (QPen (gui_colors[2]));
ui->plot->xAxis->setUpperEnding (QCPLineEnding::esSpikeArrow);
ui->plot->xAxis->setTickLabelColor (gui_colors[2]);
ui->plot->xAxis->setTickLabelFont (font);
/* Range */
ui->plot->xAxis->setRange (dataPointNumber - ui->spinPoints->value(), dataPointNumber);
/* Y Axis */
ui->plot->yAxis->grid()->setPen (QPen(gui_colors[2], 1, Qt::DotLine));
ui->plot->yAxis->grid()->setSubGridPen (QPen(gui_colors[1], 1, Qt::DotLine));
ui->plot->yAxis->grid()->setSubGridVisible (true);
ui->plot->yAxis->setBasePen (QPen (gui_colors[2]));
ui->plot->yAxis->setTickPen (QPen (gui_colors[2]));
ui->plot->yAxis->setSubTickPen (QPen (gui_colors[2]));
ui->plot->yAxis->setUpperEnding (QCPLineEnding::esSpikeArrow);
ui->plot->yAxis->setTickLabelColor (gui_colors[2]);
ui->plot->yAxis->setTickLabelFont (font);
/* Range */
ui->plot->yAxis->setRange (ui->spinAxesMin->value(), ui->spinAxesMax->value());
/* User can change Y axis tick step with a spin box */
//ui->plot->yAxis->setAutoTickStep (false);
ui->plot->yAxis->ticker()->setTickCount(ui->spinYStep->value());
/* User interactions Drag and Zoom are allowed only on X axis, Y is fixed manually by UI control */
ui->plot->setInteraction (QCP::iRangeDrag, true);
//ui->plot->setInteraction (QCP::iRangeZoom, true);
ui->plot->setInteraction (QCP::iSelectPlottables, true);
ui->plot->setInteraction (QCP::iSelectLegend, true);
ui->plot->axisRect()->setRangeDrag (Qt::Horizontal);
ui->plot->axisRect()->setRangeZoom (Qt::Horizontal);
/* Legend */
QFont legendFont;
legendFont.setPointSize(9);
ui->plot->legend->setVisible (true);
ui->plot->legend->setFont (legendFont);
ui->plot->legend->setBrush (gui_colors[3]);
ui->plot->legend->setBorderPen (gui_colors[2]);
/* By default, the legend is in the inset layout of the main axis rect. So this is how we access it to change legend placement */
ui->plot->axisRect()->insetLayout()->setInsetAlignment (0, Qt::AlignTop|Qt::AlignRight);
ui->plot->replot();
connect (ui->plot, SIGNAL(mouseWheel (QWheelEvent*)), this, SLOT (onMouseWheelInPlot(QWheelEvent*)));
connect (ui->plot, SIGNAL(mouseMove (QMouseEvent*)), this, SLOT (onMouseMoveInPlot (QMouseEvent*)));
connect (ui->plot, SIGNAL(selectionChangedByUser()), this, SLOT(channel_selection()));
//connect (ui->plot, SIGNAL(legendDoubleClick (QCPLegend*, QCPAbstractLegendItem*, QMouseEvent*)), this, SLOT(legend_double_click (QCPLegend*, QCPAbstractLegendItem*, QMouseEvent*)));
connect (&updateTimer, SIGNAL (timeout()), this, SLOT (replot()));
}
void MainWindow::enable_com_controls (bool enable)
{
ui->comboBaud->setEnabled (enable);
ui->comboData->setEnabled (enable);
ui->comboParity->setEnabled (enable);
ui->comboPort->setEnabled (enable);
ui->comboStop->setEnabled (enable);
ui->actionConnect->setEnabled (enable);
ui->actionPause_Plot->setEnabled (!enable);
ui->actionDisconnect->setEnabled (!enable);
// ui->actionRecord_stream->setEnabled(enable);
ui->actionHow_to_use->setEnabled(enable);
ui->actionSettings->setEnabled(enable);
}
void MainWindow::on_comboPort_currentIndexChanged (const QString &arg1)
{
QSerialPortInfo selectedPort (arg1); // Dislplay info for selected port
ui->statusBar->showMessage (selectedPort.description());
}
void MainWindow::replot()
{
ui->plot->xAxis->setRange (dataPointNumber - ui->spinPoints->value(), dataPointNumber);
ui->plot->replot();
}
void MainWindow::onNewDataArrived(QStringList newData)
{
static int data_members = 0;
static int channel = 0;
static int i = 0;
volatile bool you_shall_NOT_PASS = false;
/* When a fast baud rate is set (921kbps was the first to starts to bug),
this method is called multiple times (2x in the 921k tests), so a flag
is used to throttle
TO-DO: Separate processes, buffer data (1) and process data (2) */
while (you_shall_NOT_PASS) {}
you_shall_NOT_PASS = true;
if (plotting)
{
/* Get size of received list */
data_members = newData.size();
/* Parse data */
for (i = 0; i < data_members; i++)
{
/* Update number of axes if needed */
while (ui->plot->plottableCount() <= channel)
{
/* Add new channel data */
ui->plot->addGraph();
ui->plot->graph()->setPen (lineColorsList[channels % lineColorsList.size()]);
ui->plot->graph()->setName (lineColorNamesStrList[channels % lineColorNamesStrList.size()]);
if(ui->plot->legend->item(channels))
{
ui->plot->legend->item (channels)->setTextColor (lineColorsList[channels % lineColorsList.size()]);
}
ui->listWidget_Channels->addItem(ui->plot->graph()->name());
ui->listWidget_Channels->item(channel)->setForeground(QBrush(lineColorsList[channels % lineColorsList.size()]));
channels++;
}
/* [TODO] Method selection and plotting */
/* X-Y */
if (0)
{
}
/* Rolling (v1.0.0 compatible) */
else
{
/* Add data to Graph 0 */
ui->plot->graph(channel)->addData (dataPointNumber, newData[channel].toDouble());
/* Increment data number and channel */
channel++;
}
}
/* Post-parsing */
/* X-Y */
if (0)
{
}
/* Rolling (v1.0.0 compatible) */
else
{
dataPointNumber++;
channel = 0;
}
}
you_shall_NOT_PASS = false;
}
void MainWindow::on_spinPoints_valueChanged (int arg1)
{
Q_UNUSED(arg1)
int step = (float)abs(ui->spinPoints->value()) * 0.025f;
if(step == 0)
{
step = 1;
}
ui->spinPoints->setSingleStep(step);
ui->plot->xAxis->setRange (dataPointNumber - ui->spinPoints->value(), dataPointNumber);
ui->plot->replot();
}
void MainWindow::on_spinAxesMin_valueChanged(int arg1)
{
int step = (float)abs(ui->spinAxesMin->value()) * 0.025f;
if(step == 0)
{
step = 1;
}
ui->spinAxesMin->setSingleStep(step);
ui->plot->yAxis->setRangeLower (arg1);
ui->plot->replot();
}
void MainWindow::on_spinAxesMax_valueChanged(int arg1)
{
int step = (float)abs(ui->spinAxesMax->value()) * 0.025f;
if(step == 0)
{
step = 1;
}
ui->spinAxesMax->setSingleStep(step);
ui->plot->yAxis->setRangeUpper (arg1);
ui->plot->replot();
}
void MainWindow::readData()
{
if(serialPort->bytesAvailable()) { // If any bytes are available
QByteArray data = serialPort->readAll(); // Read all data in QByteArray
if(!data.isEmpty()) { // If the byte array is not empty
char *temp = data.data(); // Get a '\0'-terminated char* to the data
if(!ui->hideRecvDataCheckBox->isChecked() && ui->dataFormatCheckBox->isChecked())
{
ui->textBrowser->insertPlainText(QString(data));
}
for(int i = 0; i != data.size(); i++) { // Iterate over the char*
switch(STATE) { // Switch the current state of the message
case WAIT_START: // If waiting for start [$], examine each char
if(temp[i] == START_MSG) { // If the char is $, change STATE to IN_MESSAGE
STATE = IN_MESSAGE;
receivedData.clear(); // Clear temporary QString that holds the message
break; // Break out of the switch
}
break;
case IN_MESSAGE: // If state is IN_MESSAGE
if(temp[i] == END_MSG) { // If char examined is ;, switch state to END_MSG
STATE = WAIT_START;
QStringList incomingData = receivedData.split(' '); // Split string received from port and put it into list
if(!ui->hideRecvDataCheckBox->isChecked() && !ui->dataFormatCheckBox->isChecked())
{
ui->textBrowser->append(receivedData);
}
emit newData(incomingData); // Emit signal for data received with the list
receivedData.clear();
break;
}
else if (isdigit (temp[i]) || isspace (temp[i]) || temp[i] =='-' || temp[i] =='.')
{
/* If examined char is a digit, and not '$' or ';', append it to temporary string */
receivedData.append(temp[i]);
}
break;
default: break;
}
}
}
}
}
void MainWindow::on_spinYStep_valueChanged(int arg1)
{
ui->plot->yAxis->ticker()->setTickCount(arg1);
ui->plot->replot();
ui->spinYStep->setValue(ui->plot->yAxis->ticker()->tickCount());
}
void MainWindow::on_savePNGButton_clicked()
{
ui->plot->savePng(QDateTime::currentDateTime().toString("yyyy-MM-d-HH-mm-ss-") + QString("snapshot.png"), 1920, 1080, 2, 50);
}
void MainWindow::onMouseMoveInPlot(QMouseEvent *event)
{
int xx = int(ui->plot->xAxis->pixelToCoord(event->x()));
int yy = int(ui->plot->yAxis->pixelToCoord(event->y()));
QString coordinates("X: %1 Y: %2");
coordinates = coordinates.arg(xx).arg(yy);
ui->statusBar->showMessage(coordinates);
}
void MainWindow::onMouseWheelInPlot(QWheelEvent *event)
{
QWheelEvent inverted_event = QWheelEvent(event->posF(), event->globalPosF(),
-event->pixelDelta(), -event->angleDelta(),
0, Qt::Vertical, event->buttons(), event->modifiers());
QApplication::sendEvent (ui->spinPoints, &inverted_event);
}
void MainWindow::channel_selection (void)
{
/* synchronize selection of graphs with selection of corresponding legend items */
for (int i = 0; i < ui->plot->graphCount(); i++)
{
QCPGraph *graph = ui->plot->graph(i);
QCPPlottableLegendItem *item = ui->plot->legend->itemWithPlottable (graph);
if (item->selected())
{
item->setSelected (true);
// graph->set (true);
}
else
{
item->setSelected (false);
// graph->setSelected (false);
}
}
}
void MainWindow::legend_double_click(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
{
Q_UNUSED (legend)
Q_UNUSED(event)
/* Only react if item was clicked (user could have clicked on border padding of legend where there is no item, then item is 0) */
if (item)
{
QCPPlottableLegendItem *plItem = qobject_cast<QCPPlottableLegendItem*>(item);
bool ok;
QString newName = QInputDialog::getText (this, tr("设置通道名称"), tr("名称:"), QLineEdit::Normal, plItem->plottable()->name(), &ok, Qt::FramelessWindowHint);
if (ok)
{
plItem->plottable()->setName(newName);
for(int i=0; i<ui->plot->graphCount(); i++)
{
ui->listWidget_Channels->item(i)->setText(ui->plot->graph(i)->name());
}
ui->plot->replot();
}
}
}
void MainWindow::on_actionHow_to_use_triggered()
{
HelpWindow *helpWindow = new HelpWindow (nullptr);
helpWindow->setAttribute(Qt::WA_DeleteOnClose);
helpWindow->setModal(true);
helpWindow->show();
}
void MainWindow::on_actionConnect_triggered()
{
if (connected)
{
/* Is connected, restart if paused */
if (!plotting)
{
plotting = true;
updateTimer.start(10);
ui->actionConnect->setEnabled (false);
ui->actionPause_Plot->setEnabled (true);
ui->statusBar->showMessage (tr("开始绘制!"));
}
}
else
{
/* If application is not connected, connect */
/* Get parameters from controls first */
QSerialPortInfo portInfo (ui->comboPort->currentText()); // Temporary object, needed to create QSerialPort
int baudRate = ui->comboBaud->currentText().toInt(); // Get baud rate from combo box
int dataBitsIndex = ui->comboData->currentIndex(); // Get index of data bits combo box
int parityIndex = ui->comboParity->currentIndex(); // Get index of parity combo box
int stopBitsIndex = ui->comboStop->currentIndex(); // Get index of stop bits combo box
QSerialPort::DataBits dataBits;
QSerialPort::Parity parity;
QSerialPort::StopBits stopBits;
/* Set data bits according to the selected index */
switch (dataBitsIndex)
{
case 0:
dataBits = QSerialPort::Data8;
break;
default:
dataBits = QSerialPort::Data7;
}
/* Set parity according to the selected index */
switch (parityIndex)
{
case 0:
parity = QSerialPort::NoParity;
break;
case 1:
parity = QSerialPort::OddParity;
break;
default:
parity = QSerialPort::EvenParity;
}
/* Set stop bits according to the selected index */
switch (stopBitsIndex)
{
case 0:
stopBits = QSerialPort::OneStop;
break;
default:
stopBits = QSerialPort::TwoStop;
}
serialPort->close();
serialPort->setPort(portInfo);
serialPort->setBaudRate (baudRate);
serialPort->setParity (parity);
serialPort->setDataBits (dataBits);
serialPort->setStopBits (stopBits);
if (serialPort->open(QIODevice::ReadWrite))
{
serialPort->clear();
serialPort->clearError();
enable_com_controls (false); // Disable controls if port is open
updateTimer.start(10); // Slot is refreshed 20 times per second
connected = true; // Set flags
plotting = true;
ui->statusBar->showMessage (tr("端口打开成功!"));
}
else
{
ui->statusBar->showMessage (tr("打开失败,请检查该端口是否存在或被占用!"));
}
}
}
void MainWindow::on_actionPause_Plot_triggered()
{
if (plotting)
{
updateTimer.stop(); // Stop updating plot timer
plotting = false;
ui->actionConnect->setEnabled (true);
ui->actionPause_Plot->setEnabled (false);
ui->statusBar->showMessage (tr("暂停绘制,新数据将被忽略!"));
}
}
void MainWindow::on_actionRecord_stream_triggered()
{
if(ui->actionRecord_stream->isChecked())
{
openCsvFile();
}else
{
closeCsvFile();
}
}
void MainWindow::on_actionDisconnect_triggered()
{
if (connected)
{
serialPort->close(); // Close serial port
updateTimer.stop();
receivedData.clear(); // Clear received string
connected = false;
plotting = false;
enable_com_controls (true);
ui->statusBar->showMessage (tr("关闭端口!"));
}
}
void MainWindow::on_actionClear_triggered()
{
if(serialPort->isOpen())
{
serialPort->clear();
}
receivedData.clear();
ui->textBrowser->clear();
ui->listWidget_Channels->clear();
channels = 0;
dataPointNumber = 0;
ui->plot->clearPlottables();
ui->plot->replot();
}
void MainWindow::openCsvFile(void)
{
QString path = Settings::lastSavePath();
QString filename = QFileDialog::getSaveFileName(this, QApplication::applicationName(), path, tr("xlsx (*.xlsx)"));
if(filename.isEmpty())
{
ui->actionRecord_stream->setChecked(false);
return;
}
QDir dir;
if(dir.exists(filename))
dir.remove(filename);
QFileInfo finfo = QFileInfo(filename);
xlsxDevice = new QXlsx::Document(filename);
if(!xlsxDevice)
{
ui->actionRecord_stream->setChecked(false);
QMessageBox::critical(this, QApplication::applicationName(), tr("错误:创建%1.%2失败,请重试!").arg(finfo.baseName()).arg(finfo.completeSuffix()), QMessageBox::Close);
return;
}
xlsxRow = 1;
xlsxDevice->write(xlsxRow, 1, tr("时间"));
QStringList titles = Settings::getLineNames();
for(int i = 0; i < titles.size(); i++)
{
xlsxDevice->write(xlsxRow, i + 2, titles[i]);
}
xlsxRow++;
xlsxDevice->save();
Settings::setLastSavePath(finfo.absolutePath());
ui->statusBar->showMessage (tr("保存数据到文件!"));
}
void MainWindow::closeCsvFile(void)
{
if(xlsxDevice)
{
xlsxRow = 1;
xlsxDevice->save();
delete xlsxDevice;
xlsxDevice = nullptr;
ui->statusBar->showMessage (tr("取消保存数据到文件!"));
}
}
void MainWindow::saveStream(QStringList newData)
{
if(xlsxDevice && ui->actionRecord_stream->isChecked())
{
xlsxDevice->write(xlsxRow, 1, QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
for(int i = 0; i < newData.size(); i++)
{
xlsxDevice->write(xlsxRow, i + 2, newData[i]);
}
xlsxRow++;
xlsxDevice->save();
}
}
void MainWindow::on_pushButton_AutoScale_clicked()
{
ui->plot->yAxis->rescale(true);
ui->spinAxesMax->setValue(int(ui->plot->yAxis->range().upper) + int(ui->plot->yAxis->range().upper*0.1));
ui->spinAxesMin->setValue(int(ui->plot->yAxis->range().lower) + int(ui->plot->yAxis->range().lower*0.1));
}
void MainWindow::on_pushButton_ResetVisible_clicked()
{
for(int i=0; i<ui->plot->graphCount(); i++)
{
ui->plot->graph(i)->setVisible(true);
ui->listWidget_Channels->item(i)->setBackground(Qt::NoBrush);
}
}
void MainWindow::on_listWidget_Channels_itemDoubleClicked(QListWidgetItem *item)
{
int graphIdx = ui->listWidget_Channels->currentRow();
if(ui->plot->graph(graphIdx)->visible())
{
ui->plot->graph(graphIdx)->setVisible(false);
QBrush brush = item->background();
if(brush.style() == Qt::NoBrush)
{
brush = ui->listWidget_Channels->palette().window();
}
QColor c = brush.color();
QColor cset = QColor(255 - c.red(), 255 - c.green(), 255 - c.blue(), c.alpha());
item->setBackground(QBrush(cset));
}
else
{
ui->plot->graph(graphIdx)->setVisible(true);
item->setBackground(Qt::NoBrush);
}
ui->plot->replot();
}
void MainWindow::on_pushButton_ClearRecv_clicked()
{
ui->textBrowser->clear();
}
void MainWindow::on_actionSettings_triggered()
{
SettingsDialog* d = new SettingsDialog(nullptr);
// 退出设置自动重启软件
connect(d, &QDialog::accepted, this, [=](){
qApp->closeAllWindows(); //或qApp->quit(),但使用quit不会调用closeEvent
QProcess::startDetached(qApp->applicationFilePath(), QStringList());
});
d->setWindowTitle(tr("设置"));
d->setAttribute(Qt::WA_DeleteOnClose);
d->setModal(true); // 阻塞父窗口
d->show();
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if(event->type() == QEvent::MouseButtonPress)
{
if(watched == ui->comboPort)
{
QComboBox* comboBox = qobject_cast<QComboBox *>(watched);
comboBox->clear();
foreach (QSerialPortInfo info, QSerialPortInfo::availablePorts())
{
comboBox->addItem(info.portName());
}
}
}
return QMainWindow::eventFilter(watched, event);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。