首先安装QT5.9.9
这里时必须要用邮箱注册一个账号的,之前的版本是可以跳过这个步骤的,注册完在上面登录你的账号密码就可以下一步了。
在下一步到选择安装的组件,直接选择MinGW这个,选择这个就不用在电脑上面装VS了,我只勾选了这一个,其他的暂时用不到,然后下一步直接等到安装完成。
可以在用试着新建一个HelloWorld,具体操作参考QT学习之路2:《Qt 学习之路 2》目录 - DevBean Tech World
,基本操作也在QT学习之路2上看一下,然后用一个大神的串口上位机的例程做一些简单操作,熟悉一下。
打开所用串口例程的.pro工程文件,会提示你configure project,你直接点一下就ok,自动帮你配置好。
然后你可以在主程序里面修改一下上位机的版本信息等
我还想换一个程序的图标,然后我在:齿轮图标_站长素材这里下载了一个.ico格式的图标。
把原有文件夹下面的图片和.rc文件都删掉,换上新的图标,.rc文档里面的内容为:IDI_ICON1 ICON DISCARDABLE "main.ico"
这个文件夹下面本来还有一个.qrc文件,这个文件需要新建一个,具体方法是:
右击项目,点Add New..,出现下面界面,选择Qt,Qt Resource File然后新建一个名称放在工程目录下,这个就建好了
建好后把你图片的.ico文件放到这个目录下。
然后你重新运行一下,应用程序的图标就更改了,在再把ui界面修改一下
找个串口线,把TX,RX接一起测试一下。确认是好用的
如果有需要用qt的上位机软件工程代码,可以在下面评论告诉我你的邮箱,我看到会直接发到你的邮箱。
主函数
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyle("fusion");
MainWindow w;
w.show();
return a.exec();
}
mainwindow文件:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
createTimers();
createChart();
setupTable();
setupGUI();
settingsLoadAll();
infoDialog.setFixedSize(800, 600);
connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(on_aboutToQuitSlot()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::closeEvent(QCloseEvent *event)
{
// if (ui->pushButtonSerialConnect->isChecked() || ui->pushButtonUDPConnect->isChecked())
if (serial.isOpen() || networkUDP.isOpen())
{
QMessageBox::StandardButton resBtn = QMessageBox::question(this, "About to exit...", tr("Connection open. Are you sure ? \n"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (resBtn == QMessageBox::No)
event->ignore();
else
event->accept();
}
}
void MainWindow::on_aboutToQuitSlot()
{
qDebug() << "on_aboutToQuitSlot";
settingsSaveAll();
}
void MainWindow::createTimers()
{
this->serialDeviceCheckTimer = new QTimer(this);
this->radioButtonTimer = new QTimer(this);
this->serialStringProcessingTimer = new QTimer(this);
this->udpStringProcessingTimer = new QTimer(this);
connect(serialDeviceCheckTimer, SIGNAL(timeout()), this, SLOT(on_updateSerialDeviceList()));
connect(radioButtonTimer, &QTimer::timeout, this, [=]()
{ ui->radioButtonDeviceUpdate->setChecked(false); });
}
void MainWindow::setupGUI()
{
// ----------------------- MainWindow ----------------------- //
{
connect(ui->comboBoxSend->lineEdit(), SIGNAL(returnPressed()), this, SLOT(on_comboBoxSendReturnPressedSlot()));
this->setWindowTitle(this->windowTitle() + " " + VERSION);
}
// ---------------------------------------------------------- //
// ----------------------- textBrowserLogs ----------------------- //
{
ui->textBrowserLogs->document()->setMaximumBlockCount(ui->spinBoxMaxLines->value());
if (ui->checkBoxWrapText->isChecked() == true)
ui->textBrowserLogs->setLineWrapMode(QPlainTextEdit::LineWrapMode::WidgetWidth);
else
ui->textBrowserLogs->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap);
// highlighter = new Highlighter(ui->textBrowserLogs->document());
}
// ---------------------------------------------------------------- //
// ----------------------- standardBaudRates ----------------------- //
{
foreach (auto item, serial.getAvailibleBaudRates())
ui->comboBoxBaudRates->addItem(QString::number(item));
ui->comboBoxBaudRates->setCurrentIndex(ui->comboBoxBaudRates->count() / 2); // select middle
}
// ----------------------------------------------------------------- //
if (ui->checkBoxAutoRefresh->isChecked())
{
serialDeviceCheckTimer->start(SERIAL_DEVICE_CHECK_TIMER_INTERVAL);
ui->pushButtonRefresh->setEnabled(false);
}
else
{
ui->pushButtonRefresh->setEnabled(true);
}
// ----------------------- comboBoxGraphDisplayMode ----------------------- //
{
if (ui->comboBoxGraphDisplayMode->currentIndex() == 0)
ui->lineEditCustomParsingRules->setEnabled(false);
else
ui->lineEditCustomParsingRules->setEnabled(true);
}
// ----------------------------------------------------------------- //
ui->comboBoxExternalTimeFormat->addItem("[ms]");
ui->comboBoxExternalTimeFormat->setCurrentIndex(0);
ui->lineEditLoadFilePath->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
ui->lineEditSaveFileName->setText("Log.txt");
ui->lineEditSaveLogPath->setText(qApp->applicationDirPath() + "/Logs");
ui->splitterGraphTable->setSizes({this->height(), 0});
emit on_checkBoxAutoLogging_toggled(ui->checkBoxAutoLogging->isChecked());
emit on_checkBoxShowLegend_toggled(ui->checkBoxShowLegend->isChecked());
emit on_comboBoxClockSource_currentIndexChanged(ui->comboBoxClockSource->currentIndex());
on_updateSerialDeviceList();
}
void MainWindow::createChart()
{
// ui->widgetChart->setOpenGl(false);
ui->splitterReceivedData->setSizes(QList<int>({200, 400})); // default
ui->widgetChart->setInteractions(QCP::iRangeZoom |
QCP::iRangeDrag |
QCP::iSelectPlottables |
QCP::iSelectLegend);
QSharedPointer<QCPAxisTickerTime> xTicker(new QCPAxisTickerTime);
QSharedPointer<QCPAxisTicker> yTicker(new QCPAxisTicker);
xTicker->setTimeFormat("%h:%m:%s:%z");
xTicker->setTickCount(5);
yTicker->setTickCount(10);
yTicker->setTickStepStrategy(QCPAxisTicker::TickStepStrategy::tssReadability);
ui->widgetChart->xAxis->setTicker(xTicker);
ui->widgetChart->yAxis->setTicker(yTicker);
ui->widgetChart->axisRect()->setupFullAxesBox(true);
ui->widgetChart->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignBottom | Qt::AlignLeft);
ui->widgetChart->legend->setVisible(true);
ui->widgetChart->legend->setFont(QFont("MS Shell Dlg 2", 8, QFont::Thin, false));
ui->widgetChart->legend->setIconSize(15, 10);
ui->widgetChart->legend->setSelectableParts(QCPLegend::SelectablePart::spItems); // legend box shall not be selectable, only legend items
ui->widgetChart->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
ui->widgetChart->xAxis->setRange(-1.0, ui->spinBoxScrollingTimeRange->value());
ui->widgetChart->yAxis->setRange(-1.0, 1.0);
connect(ui->widgetChart, SIGNAL(mouseDoubleClick(QMouseEvent *)), this, SLOT(on_chartMouseDoubleClickHandler(QMouseEvent *)));
connect(ui->widgetChart, SIGNAL(mousePress(QMouseEvent *)), this, SLOT(on_chartMousePressHandler(QMouseEvent *)));
connect(ui->widgetChart, SIGNAL(mouseMove(QMouseEvent *)), this, SLOT(on_chartMouseMoveHandler(QMouseEvent *)));
connect(ui->widgetChart, SIGNAL(selectionChangedByUser()), this, SLOT(on_chartSelectionChanged()));
connect(ui->widgetChart, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(on_chartContextMenuRequest(QPoint)));
connect(ui->widgetChart, SIGNAL(beforeReplot()), this, SLOT(on_chartBeforeReplotSlot()));
// ui->widgetChart->setNotAntialiasedElements(QCP::aeAll);
if (ui->checkBoxEnableTracer->isChecked())
{
createChartTracer();
connect(ui->widgetChart, SIGNAL(mouseMove(QMouseEvent *)), this, SLOT(on_tracerShowPointValue(QMouseEvent *)));
}
ui->textBrowserLogs->setHighlightEnabled(false);
emit on_comboBoxLogFormat_currentIndexChanged(ui->comboBoxLogFormat->currentIndex());
}
void MainWindow::setupTable()
{
ui->tableWidgetParsedData->clear();
ui->tableWidgetParsedData->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
ui->tableWidgetParsedData->setColumnCount(2);
ui->tableWidgetParsedData->setHorizontalHeaderItem(0, new QTableWidgetItem("Name"));
ui->tableWidgetParsedData->setHorizontalHeaderItem(1, new QTableWidgetItem("Current Value"));
// ui->tableWidgetParsedData->setHorizontalHeaderItem(2, new QTableWidgetItem("Max"));
// ui->tableWidgetParsedData->setHorizontalHeaderItem(3, new QTableWidgetItem("Min"));
ui->tableWidgetLogTable->clear();
ui->tableWidgetLogTable->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
ui->tableWidgetLogTable->setColumnCount(1);
ui->tableWidgetLogTable->setHorizontalHeaderItem(0, new QTableWidgetItem("Time:"));
ui->tableWidgetLogTable->setSortingEnabled(true);
}
void MainWindow::settingsLoadAll()
{
QSettings appSettings(QSettings::Format::IniFormat,
QSettings::Scope::UserScope,
"Qt Vitrea", "Qt Vitrea"); // Settings
// ----- Info ----- //
{
if (appSettings.value("Info/version").value<QString>() != VERSION)
{
on_printIntroChangelog();
}
if (appSettings.value("Info/organizationName").value<QString>() != appSettings.organizationName() ||
appSettings.value("Info/applicationName").value<QString>() != appSettings.applicationName())
{
qDebug() << "Abort loading settings ! organizationName or applicationName incorrect. Config file might be missing.";
addLog("App >>\t Error loading settings. Config file incorrect !", true);
return;
}
}
// ------------------------- //
// ----- Window size ----- //
{
QStringList windowSize = appSettings.value("layout/windowSize.size").value<QString>().split(QRegExp("\\s+"), QString::SplitBehavior::SkipEmptyParts);
if (!windowSize.isEmpty())
this->resize(windowSize.first().trimmed().toInt(), windowSize.last().trimmed().toInt());
}
// ------------------------- //
// ----- splitterSizes ----- //
{
QStringList splitterSizes;
splitterSizes = appSettings.value("layout/splitterReceivedData.sizes").value<QString>().split(QRegExp("\\s+"), QString::SplitBehavior::SkipEmptyParts);
if (!splitterSizes.isEmpty())
ui->splitterReceivedData->setSizes(QList<int>({splitterSizes.first().trimmed().toInt(), splitterSizes.last().trimmed().toInt()}));
splitterSizes = appSettings.value("layout/splitterGraphTable.sizes").value<QString>().split(QRegExp("\\s+"), QString::SplitBehavior::SkipEmptyParts);
if (!splitterSizes.isEmpty())
ui->splitterGraphTable->setSizes(QList<int>({splitterSizes.first().trimmed().toInt(), splitterSizes.last().trimmed().toInt()}));
if (ui->splitterGraphTable->sizes().last() > 0)
ui->toolButtonAdvancedGraphMenu->setArrowType(Qt::ArrowType::DownArrow);
else
ui->toolButtonAdvancedGraphMenu->setArrowType(Qt::ArrowType::UpArrow);
}
// ------------------------- //
// ----- comboBoxSendItems ----- //
{
ui->comboBoxSend->addItems(QStringList(appSettings.value("data/comboBoxSendHistory").value<QString>().split(QRegExp("\\n+"), Qt::SplitBehaviorFlags::SkipEmptyParts)));
ui->comboBoxSend->lineEdit()->clear();
}
// ------------------------- //
// ----- Other GUI Elements ----- //
{
ui->checkBoxAppendDate->setChecked(appSettings.value("GUI_Elements/checkBoxAppendDate.isChecked").value<bool>());
ui->checkBoxAutoLogging->setChecked(appSettings.value("GUI_Elements/checkBoxAutoLogging.isChecked").value<bool>());
ui->checkBoxAutoRefresh->setChecked(appSettings.value("GUI_Elements/checkBoxAutoRefresh.isChecked").value<bool>());
ui->checkBoxAutoRescaleY->setChecked(appSettings.value("GUI_Elements/checkBoxAutoRescaleY.isChecked").value<bool>());
ui->checkBoxAutoSaveBuffer->setChecked(appSettings.value("GUI_Elements/checkBoxAutoSaveBuffer.isChecked", true).value<bool>());
ui->checkBoxAutoScrollLogTable->setChecked(appSettings.value("GUI_Elements/checkBoxAutoScrollLogTable.isChecked", true).value<bool>());
ui->checkBoxAutoSizeColumnsLogTable->setChecked(appSettings.value("GUI_Elements/checkBoxAutoSizeColumnsLogTable.isChecked", true).value<bool>());
ui->checkBoxAutoTrack->setChecked(appSettings.value("GUI_Elements/checkBoxAutoTrack.isChecked").value<bool>());
ui->checkBoxDTR->setChecked(appSettings.value("GUI_Elements/checkBoxDTR.isChecked").value<bool>());
ui->checkBoxEnableTracer->setChecked(appSettings.value("GUI_Elements/checkBoxEnableTracer.isChecked").value<bool>());
ui->checkBoxRAMClearChart->setChecked(appSettings.value("GUI_Elements/checkBoxRAMClearChart.isChecked").value<bool>());
ui->checkBoxScrollLogEnableSorting->setChecked(appSettings.value("GUI_Elements/checkBoxScrollLogEnableSorting.isChecked", true).value<bool>());
ui->checkBoxScrollToButtom->setChecked(appSettings.value("GUI_Elements/checkBoxScrollToButtom.isChecked").value<bool>());
ui->checkBoxSendKey->setChecked(appSettings.value("GUI_Elements/checkBoxSendKey.isChecked").value<bool>());
ui->checkBoxShowControlChars->setChecked(appSettings.value("GUI_Elements/checkBoxShowControlChars.isChecked", false).value<bool>());
ui->checkBoxSimplifyLog->setChecked(appSettings.value("GUI_Elements/checkBoxSimplifyLog.isChecked").value<bool>());
ui->checkBoxTableAutoResize->setChecked(appSettings.value("GUI_Elements/checkBoxTableAutoResize.isChecked", true).value<bool>());
ui->checkBoxTruncateFileOnSave->setChecked(appSettings.value("GUI_Elements/checkBoxTruncateFileOnSave.isChecked", false).value<bool>());
ui->checkBoxWrapText->setChecked(appSettings.value("GUI_Elements/checkBoxWrapText.isChecked").value<bool>());
ui->comboBoxAddTextMode->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxAddTextMode.currentIndex").value<int>());
ui->comboBoxBaudRates->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxBaudRates.currentIndex").value<int>());
ui->comboBoxClockSource->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxClockSource.currentIndex").value<int>());
ui->comboBoxDataBits->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxDataBits.currentIndex").value<int>());
ui->comboBoxExternalTimeFormat->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxExternalTimeFormat.currentIndex").value<int>());
ui->comboBoxFlowControl->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxFlowControl.currentIndex").value<int>());
ui->comboBoxGraphDisplayMode->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxGraphDisplayMode.currentIndex").value<int>());
ui->comboBoxLineEnding->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxLineEnding.currentIndex").value<int>());
ui->comboBoxLoggingMode->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxLoggingMode.currentIndex").value<int>());
ui->comboBoxMessagesDisplayMode->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxMessagesDisplayMode.currentIndex").value<int>());
ui->comboBoxParity->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxParity.currentIndex").value<int>());
ui->comboBoxRAMLoadMode->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxRAMLoadMode.currentIndex").value<int>());
ui->comboBoxRAMSaveMode->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxRAMSaveMode.currentIndex").value<int>());
ui->comboBoxSerialReadMode->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxSerialReadMode.currentIndex").value<int>());
ui->comboBoxStopBits->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxStopBits.currentIndex").value<int>());
ui->comboBoxTextProcessing->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxTextProcessing.currentIndex").value<int>());
ui->comboBoxTracerStyle->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxTracerStyle.currentIndex").value<int>());
ui->comboBoxUDPReceiveMode->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxUDPReceiveMode.currentIndex").value<int>());
ui->comboBoxUDPSendMode->setCurrentIndex(appSettings.value("GUI_Elements/comboBoxUDPSendMode.currentIndex").value<int>());
ui->lineEditCustomParsingRules->setText(appSettings.value("data/lineEditCustomParsingRules.text").value<QString>());
ui->lineEditExternalClockLabel->setText(appSettings.value("data/lineEditExternalClockLabel.text").value<QString>());
ui->lineEditLoadFilePath->setText(appSettings.value("data/lineEditLoadFilePath.text").value<QString>());
ui->lineEditSaveFileName->setText(appSettings.value("data/lineEditSaveFileName.text").value<QString>());
ui->lineEditSaveLogPath->setText(appSettings.value("data/lineEditSaveLogPath.text").value<QString>());
ui->lineEditUDPTargetIP->setText(appSettings.value("data/lineEditUDPTargetIP.text").value<QString>());
ui->pushButtonEnablePlot->setChecked(appSettings.value("GUI_Elements/pushButtonEnablePlot.isChecked", false).value<bool>());
ui->pushButtonEnableTableLog->setChecked(appSettings.value("GUI_Elements/pushButtonEnableTableLog.isChecked", true).value<bool>());
ui->spinBoxMaxGraphs->setValue(appSettings.value("layout/spinBoxMaxGraphs.value").value<int>());
ui->spinBoxMaxLines->setValue(appSettings.value("layout/spinBoxMaxLines.value").value<int>());
ui->spinBoxMaxRowsLogTable->setValue(appSettings.value("layout/spinBoxMaxRowsLogTable.value").value<int>());
ui->spinBoxMaxTimeRange->setValue(appSettings.value("layout/spinBoxMaxTimeRange.value").value<int>());
ui->spinBoxProcessingDelay->setValue(appSettings.value("layout/spinBoxProcessingDelay.value").value<int>());
ui->spinBoxRemoveOldLabels->setValue(appSettings.value("layout/spinBoxRemoveOldLabels.value").value<int>());
ui->spinBoxScrollingTimeRange->setValue(appSettings.value("layout/spinBoxScrollingTimeRange.value").value<int>());
ui->spinBoxUDPReceivePort->setValue(appSettings.value("layout/spinBoxUDPReceivePort.value").value<int>());
ui->spinBoxUDPTargetPort->setValue(appSettings.value("layout/spinBoxUDPTargetPort.value").value<int>());
ui->tabWidgetControlSection->setCurrentIndex(appSettings.value("GUI_Elements/tabWidgetControlSection.currentIndex").value<int>());
ui->tabWidgetTableView->setCurrentIndex(appSettings.value("GUI_Elements/tabWidgetTableView.currentIndex").value<int>());
if (ui->lineEditLoadFilePath->text().isEmpty() == false)
{
QFile file(ui->lineEditLoadFilePath->text());
QList<QTime> timeRange = fileReader.getFileTimeRange(&file);
ui->timeEditMinParsingTime->setTime(timeRange.first());
ui->timeEditMaxParsingTime->setTime(timeRange.last());
}
qDebug() << "Loaded settings";
}
}
void MainWindow::settingsSaveAll()
{
QSettings appSettings(QSettings::Format::IniFormat,
QSettings::Scope::UserScope,
"Qt Vitrea", "Qt Vitrea"); // Settings
// ----- Info ----- //
{
appSettings.setValue("Info/version", VERSION);
appSettings.setValue("Info/organizationName", appSettings.organizationName());
appSettings.setValue("Info/applicationName", appSettings.applicationName());
}
// ------------------------- //
// ----- Window size ----- //
{
QString windowSize;
windowSize = QString::number(this->size().width()) + " " + QString::number(this->size().height());
appSettings.setValue("layout/windowSize.size", windowSize);
}
// ------------------------- //
// ----- splitterSizes ----- //
{
QString splitterSizes;
splitterSizes = QString::number(ui->splitterReceivedData->sizes().first()) + " " + QString::number(ui->splitterReceivedData->sizes().last());
appSettings.setValue("layout/splitterReceivedData.sizes", splitterSizes);
splitterSizes = QString::number(ui->splitterGraphTable->sizes().first()) + " " + QString::number(ui->splitterGraphTable->sizes().last());
appSettings.setValue("layout/splitterGraphTable.sizes", splitterSizes);
}
// ------------------------- //
// ----- GUI Elements ----- //
{
appSettings.setValue("data/lineEditCustomParsingRules.text", ui->lineEditCustomParsingRules->text());
appSettings.setValue("data/lineEditExternalClockLabel.text", ui->lineEditExternalClockLabel->text());
appSettings.setValue("data/lineEditLoadFilePath.text", ui->lineEditLoadFilePath->text());
appSettings.setValue("data/lineEditSaveFileName.text", ui->lineEditSaveFileName->text());
appSettings.setValue("data/lineEditSaveLogPath.text", ui->lineEditSaveLogPath->text());
appSettings.setValue("data/lineEditUDPTargetIP.text", ui->lineEditUDPTargetIP->text());
appSettings.setValue("GUI_Elements/checkBoxAppendDate.isChecked", ui->checkBoxAppendDate->isChecked());
appSettings.setValue("GUI_Elements/checkBoxAutoLogging.isChecked", ui->checkBoxAutoLogging->isChecked());
appSettings.setValue("GUI_Elements/checkBoxAutoRefresh.isChecked", ui->checkBoxAutoRefresh->isChecked());
appSettings.setValue("GUI_Elements/checkBoxAutoRescaleY.isChecked", ui->checkBoxAutoRescaleY->isChecked());
appSettings.setValue("GUI_Elements/checkBoxAutoSaveBuffer.isChecked", ui->checkBoxAutoSaveBuffer->isChecked());
appSettings.setValue("GUI_Elements/checkBoxAutoScrollLogTable.isChecked", ui->checkBoxAutoScrollLogTable->isChecked());
appSettings.setValue("GUI_Elements/checkBoxAutoSizeColumnsLogTable.isChecked", ui->checkBoxAutoSizeColumnsLogTable->isChecked());
appSettings.setValue("GUI_Elements/checkBoxAutoTrack.isChecked", ui->checkBoxAutoTrack->isChecked());
appSettings.setValue("GUI_Elements/checkBoxDTR.isChecked", ui->checkBoxDTR->isChecked());
appSettings.setValue("GUI_Elements/checkBoxEnableTracer.isChecked", ui->checkBoxEnableTracer->isChecked());
appSettings.setValue("GUI_Elements/checkBoxRAMClearChart.isChecked", ui->checkBoxRAMClearChart->isChecked());
appSettings.setValue("GUI_Elements/checkBoxScrollLogEnableSorting.isChecked", ui->checkBoxScrollLogEnableSorting->isChecked());
appSettings.setValue("GUI_Elements/checkBoxScrollToButtom.isChecked", ui->checkBoxScrollToButtom->isChecked());
appSettings.setValue("GUI_Elements/checkBoxSendKey.isChecked", ui->checkBoxSendKey->isChecked());
appSettings.setValue("GUI_Elements/checkBoxShowControlChars.isChecked", ui->checkBoxShowControlChars->isChecked());
appSettings.setValue("GUI_Elements/checkBoxSimplifyLog.isChecked", ui->checkBoxSimplifyLog->isChecked());
appSettings.setValue("GUI_Elements/checkBoxTableAutoResize.isChecked", ui->checkBoxTableAutoResize->isChecked());
appSettings.setValue("GUI_Elements/checkBoxTruncateFileOnSave.isChecked", ui->checkBoxTruncateFileOnSave->isChecked());
appSettings.setValue("GUI_Elements/checkBoxWrapText.isChecked", ui->checkBoxWrapText->isChecked());
appSettings.setValue("GUI_Elements/comboBoxAddTextMode.currentIndex", ui->comboBoxAddTextMode->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxBaudRates.currentIndex", ui->comboBoxBaudRates->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxClockSource.currentIndex", ui->comboBoxClockSource->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxDataBits.currentIndex", ui->comboBoxDataBits->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxExternalTimeFormat.currentIndex", ui->comboBoxExternalTimeFormat->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxFlowControl.currentIndex", ui->comboBoxFlowControl->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxGraphDisplayMode.currentIndex", ui->comboBoxGraphDisplayMode->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxLineEnding.currentIndex", ui->comboBoxLineEnding->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxLoggingMode.currentIndex", ui->comboBoxLoggingMode->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxMessagesDisplayMode.currentIndex", ui->comboBoxMessagesDisplayMode->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxParity.currentIndex", ui->comboBoxParity->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxRAMLoadMode.currentIndex", ui->comboBoxRAMLoadMode->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxRAMSaveMode.currentIndex", ui->comboBoxRAMSaveMode->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxSerialReadMode.currentIndex", ui->comboBoxSerialReadMode->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxStopBits.currentIndex", ui->comboBoxStopBits->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxTextProcessing.currentIndex", ui->comboBoxTextProcessing->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxTracerStyle.currentIndex", ui->comboBoxTracerStyle->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxUDPReceiveMode.currentIndex", ui->comboBoxUDPReceiveMode->currentIndex());
appSettings.setValue("GUI_Elements/comboBoxUDPSendMode.currentIndex", ui->comboBoxUDPSendMode->currentIndex());
appSettings.setValue("GUI_Elements/pushButtonEnablePlot.isChecked", ui->pushButtonEnablePlot->isChecked());
appSettings.setValue("GUI_Elements/tabWidgetControlSection.currentIndex", ui->tabWidgetControlSection->currentIndex());
appSettings.setValue("GUI_Elements/tabWidgetTableView.currentIndex", ui->tabWidgetTableView->currentIndex());
appSettings.setValue("layout/pushButtonEnableTableLog.isChecked", ui->pushButtonEnableTableLog->isChecked());
appSettings.setValue("layout/spinBoxMaxGraphs.value", ui->spinBoxMaxGraphs->value());
appSettings.setValue("layout/spinBoxMaxLines.value", ui->spinBoxMaxLines->value());
appSettings.setValue("layout/spinBoxMaxRowsLogTable.value", ui->spinBoxMaxRowsLogTable->value());
appSettings.setValue("layout/spinBoxMaxTimeRange.value", ui->spinBoxMaxTimeRange->value());
appSettings.setValue("layout/spinBoxProcessingDelay.value", ui->spinBoxProcessingDelay->value());
appSettings.setValue("layout/spinBoxRemoveOldLabels.value", ui->spinBoxRemoveOldLabels->value());
appSettings.setValue("layout/spinBoxScrollingTimeRange.value", ui->spinBoxScrollingTimeRange->value());
appSettings.setValue("layout/spinBoxUDPReceivePort.value", ui->spinBoxUDPReceivePort->value());
appSettings.setValue("layout/spinBoxUDPTargetPort.value", ui->spinBoxUDPTargetPort->value());
}
// ------------------------- //
// ----- comboBoxSendItems ----- //
{
QString comboBoxSendItems;
for (auto i = 0; i < ui->comboBoxSend->count(); ++i)
comboBoxSendItems.append(ui->comboBoxSend->itemText(i) + "\n");
qDebug() << comboBoxSendItems;
appSettings.setValue("data/comboBoxSendHistory", comboBoxSendItems);
}
// ------------------------- //
appSettings.sync();
qDebug() << "Save all settings";
}
void MainWindow::processTable(QStringList labels, QList<double> values)
{
static QList<int> tableMissingCount;
foreach (auto label, labels)
{
if (ui->tableWidgetParsedData->findItems(label, Qt::MatchFlag::MatchExactly).count() < 1)
{
ui->tableWidgetParsedData->insertRow(ui->tableWidgetParsedData->rowCount());
QTableWidgetItem *newLabel = new QTableWidgetItem(label);
ui->tableWidgetParsedData->setItem(ui->tableWidgetParsedData->rowCount() - 1, 0, newLabel);
tableMissingCount.append(0);
}
for (auto i = 0; i < ui->tableWidgetParsedData->rowCount(); ++i)
{
if (ui->tableWidgetParsedData->item(i, 0)->text() == label)
{
QTableWidgetItem *newValue = new QTableWidgetItem(QString::number(values[labels.indexOf(label)]));
ui->tableWidgetParsedData->setItem(i, 1, newValue);
break;
}
}
if (ui->spinBoxRemoveOldLabels->value() > 0)
{
for (auto i = 0; i < ui->tableWidgetParsedData->rowCount(); ++i)
{
if (ui->tableWidgetParsedData->item(i, 0)->text() == label)
tableMissingCount[i] = 0;
else
tableMissingCount[i]++;
if (tableMissingCount[i] > ui->spinBoxRemoveOldLabels->value())
{
ui->tableWidgetParsedData->removeRow(i);
tableMissingCount.removeAt(i);
}
}
}
}
if (ui->checkBoxTableAutoResize->isChecked())
{
ui->tableWidgetParsedData->resizeColumnsToContents();
ui->tableWidgetParsedData->resizeRowsToContents();
}
}
void MainWindow::processLogTable(QList<long> timeTable, QStringList labelTable, QList<double> valueTable)
{
if (ui->pushButtonEnableTableLog->isChecked())
return;
// static QList<int> tableMissingCount;
unsigned long oldRowCount = ui->tableWidgetLogTable->rowCount();
QStringList firstRow;
for (auto i = 0; i < ui->tableWidgetLogTable->columnCount(); ++i)
firstRow.append(ui->tableWidgetLogTable->horizontalHeaderItem(i)->text().trimmed());
bool resizeFlag = false;
foreach (auto label, labelTable)
{
if (firstRow.contains(label) == false) // optimise
{
ui->tableWidgetLogTable->setColumnCount(ui->tableWidgetLogTable->columnCount() + 1);
ui->tableWidgetLogTable->setHorizontalHeaderItem(ui->tableWidgetLogTable->columnCount() - 1, new QTableWidgetItem(label.trimmed()));
firstRow.clear();
for (auto i = 0; i < ui->tableWidgetLogTable->columnCount(); ++i)
firstRow.append(ui->tableWidgetLogTable->horizontalHeaderItem(i)->text().trimmed());
resizeFlag = true;
}
else
{
if (oldRowCount == ui->tableWidgetLogTable->rowCount())
ui->tableWidgetLogTable->setRowCount(oldRowCount + 1);
ui->tableWidgetLogTable->setItem(oldRowCount, 0, new QTableWidgetItem(QTime::fromMSecsSinceStartOfDay(timeTable[labelTable.indexOf(label)]).toString(parser.searchTimeFormatList[0])));
ui->tableWidgetLogTable->setItem(oldRowCount, firstRow.indexOf(label), new QTableWidgetItem(QString::number(valueTable[labelTable.indexOf(label)])));
}
}
if (ui->checkBoxAutoScrollLogTable->isChecked())
ui->tableWidgetLogTable->scrollToBottom();
if (ui->checkBoxAutoSizeColumnsLogTable->isChecked() && resizeFlag)
ui->tableWidgetLogTable->resizeColumnsToContents();
if (ui->spinBoxMaxRowsLogTable->value() > 0)
{
while (ui->tableWidgetLogTable->rowCount() > ui->spinBoxMaxRowsLogTable->value())
{
ui->tableWidgetLogTable->removeRow(0);
}
}
}
void MainWindow::on_printIntroChangelog() // TODO
{
ui->pushButtonTextLogToggle->setChecked(false);
ui->textBrowserLogs->appendPlainText(INTRO_TEXT);
ui->textBrowserLogs->appendPlainText("\n" CHANGELOG_TEXT);
// ui->textBrowserLogs->horizontalScrollBar()->setValue(0);
}
void MainWindow::on_comboBoxSendReturnPressedSlot()
{
sendMessageLineEdit(ui->tabWidgetControlSection->currentIndex());
}
void MainWindow::sendMessageLineEdit(int mode)
{
if (mode == 0)
sendSerial(ui->comboBoxSend->currentText());
else if (mode == 1)
sendUDPDatagram(ui->comboBoxSend->currentText());
else
{
sendSerial(ui->comboBoxSend->currentText()); // TODO
sendUDPDatagram(ui->comboBoxSend->currentText());
}
if (ui->comboBoxMessagesDisplayMode->currentIndex() == 0)
addLog("\n >> " + ui->comboBoxSend->currentText(), ui->comboBoxAddTextMode->currentIndex());
ui->comboBoxSend->setCurrentText("");
ui->comboBoxSend->model()->sort(0, Qt::SortOrder::AscendingOrder); // sort alphabetically
}
// Auto-scroll X and rescale Y
void MainWindow::on_chartBeforeReplotSlot()
{
static bool isChartEmpty = false;
if (ui->widgetChart->graphCount() > 0 && isChartEmpty == true)
{
isChartEmpty = false;
ui->widgetChart->rescaleAxes(); // center plot if new graphs added to empty chart
}
else if (ui->widgetChart->graphCount() == 0)
{
isChartEmpty = true;
}
if (ui->checkBoxAutoTrack->isChecked() && ui->widgetChart->graphCount() > 0)
{
if (parser.getListTimeStamp().count() > 0)
{
ui->widgetChart->xAxis->setRange((parser.getListTimeStamp().last() / 1000.0) + (ui->spinBoxScrollingTimeRange->value() * 0.05),
ui->spinBoxScrollingTimeRange->value(), Qt::AlignRight);
}
if (ui->checkBoxAutoRescaleY->isChecked())
{
bool atLeastOneGraphVisible = false, atLeastOneGraphIsNotFlat = false;
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
if (ui->widgetChart->graph(i)->visible())
{
atLeastOneGraphVisible = true;
bool foundRange = false;
QCPRange valueRange = ui->widgetChart->graph(i)->data().data()->valueRange(foundRange);
if (foundRange == true && abs(valueRange.upper - valueRange.lower) >= 0.1)
atLeastOneGraphIsNotFlat = true;
}
}
if (atLeastOneGraphVisible && atLeastOneGraphIsNotFlat)
{
ui->widgetChart->yAxis->rescale(true);
ui->widgetChart->yAxis->scaleRange(1.20); // leave some space at the top and buttom of the chart.
}
}
}
else
{
// do nothing ?
}
}
void MainWindow::on_chartContextMenuRequest(QPoint pos) // right click on chart
{
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
if (ui->widgetChart->legend->selectTest(pos, false) >= 0) // context menu on legend requested
{
on_clearGraphSelection();
for (auto i = 0; i < ui->widgetChart->legend->itemCount(); ++i)
{
if (ui->widgetChart->legend->item(i)->selectTest(pos, false) >= 0)
{
ui->widgetChart->legend->item(i)->setSelected(true);
menu->addAction("Show excusively", this, SLOT(on_showSelectedGraphExclusively()));
if (ui->widgetChart->graph(i)->visible())
menu->addAction("Hide graph", this, SLOT(on_hideSelectedGraph()));
else
menu->addAction("Show graph", this, SLOT(on_showSelectedGraph()));
}
}
}
else
{
for (auto i = 0; i < ui->widgetChart->legend->itemCount(); ++i) // context menu requested eslewhere on the graph
{
if (ui->widgetChart->legend->item(i)->selected())
{
menu->addAction("Show excusively", this, SLOT(on_showSelectedGraphExclusively()));
if (ui->widgetChart->graph(i)->visible())
menu->addAction("Hide graph", this, SLOT(on_hideSelectedGraph()));
else
menu->addAction("Show graph", this, SLOT(on_showSelectedGraph()));
}
}
}
if (ui->widgetChart->graphCount() > 0)
{
menu->addAction("Show all graphs", this, SLOT(on_showAllGraphs()));
menu->addAction("Hide all graphs", this, SLOT(on_hideAllGraphs()));
}
menu->popup(ui->widgetChart->mapToGlobal(pos));
ui->widgetChart->replot();
}
void MainWindow::on_showSelectedGraphExclusively()
{
on_hideAllGraphs();
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
if (ui->widgetChart->graph(i)->selected() || ui->widgetChart->legend->item(i)->selected())
{
ui->widgetChart->graph(i)->setVisible(true);
ui->widgetChart->legend->item(i)->setTextColor(Qt::GlobalColor::black);
ui->widgetChart->replot();
return;
}
}
}
void MainWindow::on_showAllGraphs()
{
for (auto i = 0; i < ui->widgetChart->legend->itemCount(); ++i)
{
ui->widgetChart->graph(i)->setVisible(true);
ui->widgetChart->legend->item(i)->setTextColor(Qt::GlobalColor::black);
}
ui->widgetChart->replot();
}
void MainWindow::on_clearGraphSelection()
{
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
ui->widgetChart->legend->item(i)->setSelected(false);
}
}
void MainWindow::on_hideSelectedGraph()
{
for (auto i = 0; i < ui->widgetChart->legend->itemCount(); ++i)
{
if (ui->widgetChart->legend->item(i)->selected())
{
ui->widgetChart->graph(i)->setVisible(false);
ui->widgetChart->legend->item(i)->setTextColor(Qt::GlobalColor::gray);
}
}
on_clearGraphSelection();
ui->widgetChart->replot();
}
void MainWindow::on_showSelectedGraph()
{
for (auto i = 0; i < ui->widgetChart->legend->itemCount(); ++i)
{
if (ui->widgetChart->legend->item(i)->selected())
{
ui->widgetChart->graph(i)->setVisible(true);
ui->widgetChart->legend->item(i)->setTextColor(Qt::GlobalColor::black);
}
}
on_clearGraphSelection();
ui->widgetChart->replot();
}
void MainWindow::on_hideAllGraphs()
{
if (ui->widgetChart->graphCount() > 0)
{
for (auto i = 0; i < ui->widgetChart->legend->itemCount(); ++i)
{
ui->widgetChart->graph(i)->setVisible(false);
ui->widgetChart->legend->item(i)->setTextColor(Qt::GlobalColor::gray);
}
ui->widgetChart->replot();
}
}
void MainWindow::on_chartMouseDoubleClickHandler(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
ui->widgetChart->rescaleAxes(true);
ui->widgetChart->yAxis->scaleRange(1.20);
}
else if (event->button() == Qt::MiddleButton)
{
ui->checkBoxAutoTrack->setChecked(!ui->checkBoxAutoTrack->isChecked());
}
ui->widgetChart->replot();
}
void MainWindow::on_chartSelectionChanged()
{
// synchronize selection of graphs with selection of corresponding legend items:
for (int i = 0; i < ui->widgetChart->graphCount(); ++i)
{
QCPGraph *selectedGraph = ui->widgetChart->graph(i);
QCPPlottableLegendItem *selectedLegendItem = ui->widgetChart->legend->itemWithPlottable(selectedGraph);
if (selectedLegendItem->selected() || selectedGraph->selected())
{
selectedLegendItem->setSelected(true);
selectedGraph->setSelection(QCPDataSelection(selectedGraph->data()->dataRange()));
return;
}
}
}
void MainWindow::on_tracerShowPointValue(QMouseEvent *event)
{
if (ui->widgetChart->graphCount() < 1)
return;
// Get selected graph (in my case selected means the plot is selected from the legend)
QCPGraph *graph = nullptr;
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
if (ui->widgetChart->graph(i)->selected())
{
graph = ui->widgetChart->graph(i);
break;
}
}
if (graph == nullptr)
return;
// Setup the item tracer
this->phaseTracer->setGraph(graph);
this->phaseTracer->setGraphKey(ui->widgetChart->xAxis->pixelToCoord(event->pos().x()));
ui->widgetChart->replot();
// **********Get the values from the item tracer's coords***********
QPointF temp = this->phaseTracer->position->coords();
// Show a tooltip which tells the values
QToolTip::showText(event->globalPos(),
tr("<h4>%L1</h4>"
"<table>"
"<tr>"
"<td>X: %L2</td>"
"<td> , </td>"
"<td>Y: %L3</td>"
"</tr>"
"</table>")
.arg(graph->name())
.arg(QTime::fromMSecsSinceStartOfDay(temp.x() * 1000).toString("hh:mm:ss:zzz"))
.arg(QString::number(temp.y(), 'f', 5)),
ui->widgetChart, ui->widgetChart->rect());
}
// Activates rect mode on middle button press
void MainWindow::on_chartMousePressHandler(QMouseEvent *event)
{
if (event->button() == Qt::MiddleButton)
ui->widgetChart->setSelectionRectMode(QCP::srmZoom);
else
ui->widgetChart->setSelectionRectMode(QCP::srmNone);
ui->widgetChart->replot();
}
void MainWindow::on_chartMouseMoveHandler(QMouseEvent *event)
{
static int distance = 0, lastPos = 0;
if (event->buttons() & Qt::LeftButton)
{
distance += event->pos().x() - lastPos;
lastPos = event->pos().x();
// qDebug() << "distance: " + QString::number(distance);
if (abs(distance) > 200)
{
ui->checkBoxAutoTrack->setChecked(false);
}
}
else
{
distance = 0;
}
}
void MainWindow::on_updateSerialDeviceList()
{
QList<QSerialPortInfo> devices = serial.getAvailiblePorts();
QList<QString> portNames;
static QList<QString> portNamesOld;
foreach (auto item, devices)
portNames.append(item.portName());
if ((devices.count() >= 1) && (!(portNames.toSet().intersects(portNamesOld.toSet())) || (portNames.count() != portNamesOld.count())))
{
ui->comboBoxDevices->clear();
for (auto i = 0; i < devices.count(); ++i)
{
ui->comboBoxDevices->addItem("(" + devices.at(i).portName() + ")" + " " + devices.at(i).description());
}
}
else if ((devices.count() < 1) && !ui->comboBoxDevices->itemText(0).startsWith("No COM devices"))
{
ui->comboBoxDevices->clear();
ui->comboBoxDevices->addItem("No serial devices detected :(");
ui->comboBoxDevices->setCurrentIndex(ui->comboBoxDevices->count() - 1);
}
portNamesOld = portNames;
this->radioButtonTimer->start(RADIO_BUTTON_UPDATE_SERIAL_DEVICES_ON_INTERVAL);
ui->radioButtonDeviceUpdate->setChecked(true);
}
void MainWindow::on_pushButtonRefresh_clicked()
{
qDebug() << "Refreshing serial device list...";
this->addLog("App >>\t Searching for COM ports...", true);
this->on_updateSerialDeviceList();
}
void MainWindow::addLog(QString text, bool appendAsLine)
{
if (ui->pushButtonTextLogToggle->isChecked() == false)
{
QString currentDateTime = QDateTime::currentDateTime().toString("hh:mm:ss:zzz ");
if (ui->checkBoxShowTime->isChecked())
text = currentDateTime + text;
// Replace control chars
if (ui->checkBoxShowControlChars->isChecked())
text = controlCharactersVisibleConvert(text);
if (!appendAsLine)
{
int sliderPosVertical = ui->textBrowserLogs->verticalScrollBar()->value();
int sliderPosHorizontal = ui->textBrowserLogs->horizontalScrollBar()->value();
ui->textBrowserLogs->moveCursor(QTextCursor::MoveOperation::End, QTextCursor::MoveMode::MoveAnchor);
ui->textBrowserLogs->insertPlainText(text);
ui->textBrowserLogs->horizontalScrollBar()->setValue(sliderPosHorizontal);
if (!ui->checkBoxScrollToButtom->isChecked())
ui->textBrowserLogs->verticalScrollBar()->setValue(sliderPosVertical);
else
ui->textBrowserLogs->verticalScrollBar()->setValue(ui->textBrowserLogs->verticalScrollBar()->maximum());
}
else
{
ui->textBrowserLogs->appendPlainText(text);
}
}
}
QString MainWindow::controlCharactersVisibleConvert(QString text)
{
if (text.replace("\r\n", "\\r\\n\r\n").isEmpty())
{
text.replace("\r", "\\r\r");
text.replace("\n", "\\n\n");
}
text.replace("\t", "\\t\t");
text.replace(' ', QChar(183));
return text;
}
void MainWindow::addLogBytes(QByteArray bytes, bool hexToBinary, bool appendAsLine)
{
if (ui->pushButtonTextLogToggle->isChecked() == false)
{
QString currentDateTime = QDateTime::currentDateTime().toString("hh:mm:ss:zzz ");
QString bytesText;
if (hexToBinary == false)
bytesText = bytes.toHex(' ');
else
{
for (auto i = 0; i < bytes.size(); ++i)
{
bytesText.append(QString::number(bytes[i], 2) + ' ');
}
}
if (ui->checkBoxShowTime->isChecked())
bytesText = currentDateTime + bytesText;
if (!appendAsLine)
{
int sliderPosVertical = ui->textBrowserLogs->verticalScrollBar()->value();
int sliderPosHorizontal = ui->textBrowserLogs->horizontalScrollBar()->value();
ui->textBrowserLogs->moveCursor(QTextCursor::MoveOperation::End, QTextCursor::MoveMode::MoveAnchor);
ui->textBrowserLogs->insertPlainText(bytesText);
ui->textBrowserLogs->horizontalScrollBar()->setValue(sliderPosHorizontal);
if (!ui->checkBoxScrollToButtom->isChecked())
ui->textBrowserLogs->verticalScrollBar()->setValue(sliderPosVertical);
else
ui->textBrowserLogs->verticalScrollBar()->setValue(ui->textBrowserLogs->verticalScrollBar()->maximum());
}
else
{
ui->textBrowserLogs->appendPlainText(bytesText);
}
}
}
void MainWindow::processLogWrite(QString rawLine, QStringList labelList, QList<double> dataList, QList<long> timeList)
{
if (ui->pushButtonLogging->isChecked()) // Write log into file
{
if (ui->comboBoxLogFormat->currentIndex() == 1)
{
if (ui->comboBoxLoggingMode->currentIndex() == 0)
fileLogger.writeLogTXTLine(rawLine, ui->checkBoxSimplifyLog->isChecked());
else if (ui->comboBoxLoggingMode->currentIndex() == 1)
fileLogger.writeLogTXTParsedData(labelList, dataList);
}
else if (ui->comboBoxLogFormat->currentIndex() == 0)
{
fileLogger.writeLogCSV(labelList, dataList);
}
}
}
void MainWindow::on_processSerial()
{
QString serialInput = serial.getString();
serial.clearAll();
if (ui->comboBoxTextProcessing->currentIndex() == 1) // Append text to textBrowser
serialInput = serialInput.trimmed();
else if (ui->comboBoxTextProcessing->currentIndex() == 2)
serialInput = serialInput.simplified();
if (ui->comboBoxFormat->currentIndex() == 0 && serialInput.isEmpty() == false)
{
addLog(serialInput, ui->comboBoxAddTextMode->currentIndex());
}
else if (ui->comboBoxFormat->currentIndex() == 1 && serialInput.length() > 0)
{
addLogBytes(serialInput.toUtf8(), false, ui->comboBoxAddTextMode->currentIndex());
}
else if (ui->comboBoxFormat->currentIndex() == 2 && serialInput.length() > 0)
{
addLogBytes(serialInput.toUtf8(), true, ui->comboBoxAddTextMode->currentIndex());
}
if (serialInput.isEmpty() == false)
{
parser.parse(serialInput, ui->comboBoxClockSource->currentIndex() == 0, ui->comboBoxClockSource->currentIndex() == 1, ui->lineEditExternalClockLabel->text()); // Parse string - split into labels + numeric data
QStringList labelList = parser.getStringListLabels();
QList<double> numericDataList = parser.getListNumericValues();
QList<long> timeStamps = parser.getListTimeStamp();
this->processChart(labelList, numericDataList, timeStamps);
this->processLogWrite(serialInput, labelList, numericDataList, timeStamps);
this->saveToRAM(labelList, numericDataList, timeStamps, ui->comboBoxRAMSaveMode->currentIndex(), serialInput);
this->processTable(labelList, numericDataList);
this->processLogTable(timeStamps, labelList, numericDataList);
// QFuture<void> future = QtConcurrent::run([=]() // Cool !
// {
// });
}
}
void MainWindow::clearGraphData(bool replot)
{
qDebug() << "clear graph data!";
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
ui->widgetChart->graph(i)->data().data()->clear();
}
if (replot)
ui->widgetChart->replot();
}
void MainWindow::on_processUDP()
{
QString udpInput = networkUDP.readString();
networkUDP.clearAll();
if (ui->comboBoxTextProcessing->currentIndex() == 1)
udpInput = udpInput.trimmed();
else if (ui->comboBoxTextProcessing->currentIndex() == 2)
udpInput = udpInput.simplified();
if (ui->comboBoxFormat->currentIndex() == 0 && udpInput.isEmpty() == false)
{
addLog(udpInput);
}
else if (ui->comboBoxFormat->currentIndex() == 1 && udpInput.length() > 0)
{
addLogBytes(udpInput.toUtf8(), false, ui->comboBoxAddTextMode->currentIndex());
}
else if (ui->comboBoxFormat->currentIndex() == 2 && udpInput.length() > 0)
{
addLogBytes(udpInput.toUtf8(), true, ui->comboBoxAddTextMode->currentIndex());
}
if (udpInput.isEmpty() == false)
{
parser.parse(udpInput, ui->comboBoxClockSource->currentIndex() == 0, ui->comboBoxClockSource->currentIndex() == 1, ui->lineEditExternalClockLabel->text()); // Parse string - split into labels + numeric data
QStringList labelList = parser.getStringListLabels();
QList<double> numericDataList = parser.getListNumericValues();
QList<long> timeStamps = parser.getListTimeStamp();
this->processLogWrite(udpInput, labelList, numericDataList, timeStamps);
this->processChart(labelList, numericDataList, timeStamps);
this->saveToRAM(labelList, numericDataList, timeStamps, ui->comboBoxRAMSaveMode->currentIndex(), udpInput);
this->processTable(labelList, numericDataList); // Fill tableWidget
this->processLogTable(timeStamps, labelList, numericDataList);
}
}
void MainWindow::sendUDPDatagram(QString message)
{
if (!networkUDP.isOpen())
{
addLog("App >>\t Unable to send - port closed.", true);
return;
}
if (ui->comboBoxLineEnding->currentIndex() == 1)
{
message = message + "\n";
}
else if (ui->comboBoxLineEnding->currentIndex() == 2)
{
message = message + "\r";
}
else if (ui->comboBoxLineEnding->currentIndex() == 3)
{
message = message + "\r\n";
}
if (ui->comboBoxUDPSendMode->currentText().contains("Broadcast", Qt::CaseSensitivity::CaseInsensitive))
{
networkUDP.write(message, QHostAddress::Broadcast, ui->spinBoxUDPTargetPort->value());
}
else if (ui->comboBoxUDPSendMode->currentText().contains("LocalHost", Qt::CaseSensitivity::CaseInsensitive))
{
networkUDP.write(message, QHostAddress::LocalHost, ui->spinBoxUDPTargetPort->value());
}
else
{
networkUDP.write(message, QHostAddress(ui->lineEditUDPTargetIP->text()), ui->spinBoxUDPTargetPort->value());
}
// addLog("UDP >>\t" + message);
}
void MainWindow::processChart(QStringList labelList, QList<double> numericDataList, QList<long> timeStampsList)
{
if (timeStampsList.count() == 0 || labelList.count() == 0 || numericDataList.count() == 0 || ui->pushButtonEnablePlot->isChecked())
return;
// Execute plotter
foreach (auto label, labelList)
{
bool canAddGraph = true;
if (ui->widgetChart->graphCount() > 0)
{
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
if (ui->widgetChart->graph(i)->name() == label)
{
canAddGraph = false;
break;
}
}
}
if (canAddGraph && ui->widgetChart->graphCount() < ui->spinBoxMaxGraphs->value() &&
((ui->comboBoxGraphDisplayMode->currentIndex() == 0) ||
(ui->comboBoxGraphDisplayMode->currentIndex() == 1 &&
ui->lineEditCustomParsingRules->text().simplified().contains(label, Qt::CaseSensitivity::CaseSensitive)) ||
(ui->comboBoxGraphDisplayMode->currentIndex() == 2 &&
!ui->lineEditCustomParsingRules->text().simplified().contains(label, Qt::CaseSensitivity::CaseSensitive))))
{
ui->widgetChart->addGraph();
ui->widgetChart->graph()->setName(label);
ui->widgetChart->graph()->selectionDecorator()->setPen(QPen(Qt::black, 1.0, Qt::PenStyle::DashLine));
while (ui->widgetChart->graph()->lineStyle() == (QCPGraph::LineStyle::lsImpulse)) //
ui->widgetChart->graph()->setLineStyle((QCPGraph::LineStyle)(rand() % 5 + 1)); // random line except for impulse
while (ui->widgetChart->graph()->scatterStyle().shape() == QCPScatterStyle::ScatterShape::ssNone)
ui->widgetChart->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)(rand() % 14 + 1))); // random scatter
int hue = 0; // start with red
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
ui->widgetChart->graph(i)->setPen(QPen(QColor::fromHsv(hue, 255, 200))); // random color
hue += 360 / ui->widgetChart->graphCount();
}
missingCount.append(0); // Add missing counter to the list (corresponds to each graph index)
}
}
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
for (auto j = 0; j < labelList.count(); ++j)
{
if (labelList[j] == ui->widgetChart->graph(i)->name()) // If label matches the graphs name - we can start add points to it
{
if (timeStampsList[j] > 0) // if == 0 then we assume that no external clock was parsed propely
ui->widgetChart->graph(i)->addData(timeStampsList[j] / 1000.0, numericDataList[j]);
// break; // no break - slower but if we keep checking for duplicates, we can add multiple points at once
}
}
if (ui->spinBoxMaxTimeRange->value() > 0)
ui->widgetChart->graph(i)->data().data()->removeBefore((timeStampsList.last() / 1000.0) - ui->spinBoxMaxTimeRange->value()); // Remove old points
if (ui->spinBoxRemoveOldLabels->value() > 0)
{
if (labelList.contains(ui->widgetChart->graph(i)->name()))
missingCount[i] = 0;
else
missingCount[i]++;
if (missingCount[i] > ui->spinBoxRemoveOldLabels->value())
{
ui->widgetChart->removeGraph(i);
missingCount.removeAt(i); // Remove entry for this label
}
}
}
ui->widgetChart->replot();
}
void MainWindow::on_setSelectedLabels(QList<QString> *labels, bool customRules)
{
qDebug() << "on_setSelectedLabels";
if (!customRules)
{
if (labels->count() < 1)
{
on_showAllGraphs();
ui->lineEditCustomParsingRules->clear();
}
else
{
on_hideAllGraphs();
if (ui->widgetChart->graphCount() > 0)
{
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
if (labels->contains(ui->widgetChart->graph(i)->name()))
{
ui->widgetChart->legend->item(i)->setSelected(true);
on_showSelectedGraph();
}
}
}
}
}
else
{
ui->comboBoxGraphDisplayMode->setCurrentIndex(1);
}
QString labelsToAppend;
foreach (QString item, *labels)
labelsToAppend.append(item + " ");
ui->lineEditCustomParsingRules->setText(labelsToAppend);
emit on_lineEditCustomParsingRules_editingFinished();
}
void MainWindow::clearGraphs(bool replot)
{
ui->widgetChart->clearGraphs();
if (replot)
ui->widgetChart->replot();
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (ui->textBrowserLogs->hasFocus())
{
if (event->key() == Qt::Key_Alt)
{
qDebug() << "Scrolling to buttom !" + QString::number(event->key());
ui->textBrowserLogs->verticalScrollBar()->setValue(ui->textBrowserLogs->verticalScrollBar()->maximum());
}
else if (ui->checkBoxSendKey->isChecked())
{
sendMessageKeyEvent(event);
if (ui->comboBoxMessagesDisplayMode->currentIndex() == 0)
addLog(">>\n\t" + event->text(), ui->comboBoxAddTextMode->currentIndex());
}
}
else if (ui->widgetChart->hasFocus())
{
if (event->key() == Qt::Key_T)
{
ui->checkBoxEnableTracer->toggle();
}
else if (event->key() == Qt::Key_X)
{
ui->checkBoxAutoTrack->toggle();
}
else if (event->key() == Qt::Key_Y)
{
ui->checkBoxAutoRescaleY->toggle();
}
else if (event->key() == Qt::Key_L)
{
ui->checkBoxShowLegend->toggle();
}
}
if (event->key() == Qt::Key::Key_F1)
{
QWhatsThis::enterWhatsThisMode();
}
}
void MainWindow::sendMessageKeyEvent(QKeyEvent *event)
{
if (ui->tabWidgetControlSection->currentIndex() == 0)
sendSerial(event->text());
else if (ui->tabWidgetControlSection->currentIndex() == 1)
sendUDPDatagram(event->text());
else
{
sendSerial(event->text());
sendUDPDatagram(event->text());
}
}
void MainWindow::sendSerial(QString message) // TODO - move to serial - error via signal/slot
{
if (ui->comboBoxLineEnding->currentIndex() == 1)
{
message = message + "\n";
}
else if (ui->comboBoxLineEnding->currentIndex() == 2)
{
message = message + "\r";
}
else if (ui->comboBoxLineEnding->currentIndex() == 3)
{
message = message + "\r\n";
}
if (!serial.send(message))
this->addLog("App >>\t Unable to send! Serial port closed !", true);
}
void MainWindow::saveToRAM(QStringList newlabelList, QList<double> newDataList, QList<long> newTimeList, bool saveText, QString text)
{
if (ui->checkBoxAutoSaveBuffer->isChecked() == false)
return;
if (text.isEmpty() == false && saveText == true)
parser.appendSetToMemory(newlabelList, newDataList, newTimeList, text);
else
parser.appendSetToMemory(newlabelList, newDataList, newTimeList);
}
void MainWindow::loadFromRAM(bool loadText)
{
QStringList RAMLabels = parser.getLabelStorage();
QList<double> RAMData = parser.getDataStorage();
QList<long> RAMTime = parser.getTimeStorage();
if (loadText)
{
QStringList RAMText = parser.getTextList();
foreach (auto line, RAMText)
addLog("Mem >>\t" + line);
}
if (RAMLabels.isEmpty() || RAMData.isEmpty() || RAMTime.isEmpty())
return;
this->processChart(RAMLabels, RAMData, RAMTime);
this->processTable(RAMLabels, RAMData);
this->processLogTable(RAMTime, RAMLabels, RAMData);
}
void MainWindow::on_checkBoxAutoRefresh_toggled(bool checked)
{
if (checked == true)
{
ui->pushButtonRefresh->setEnabled(false);
serialDeviceCheckTimer->start(SERIAL_DEVICE_CHECK_TIMER_INTERVAL);
}
else
{
ui->pushButtonRefresh->setEnabled(true);
serialDeviceCheckTimer->stop();
}
}
void MainWindow::on_pushButtonClear_clicked()
{
ui->textBrowserLogs->clear();
}
void MainWindow::on_lineEditHighlight_returnPressed()
{
on_highlighLog(ui->lineEditHighlight->text());
}
void MainWindow::on_highlighLog(QString searchString)
{
QTextDocument *document = ui->textBrowserLogs->document();
QTextCursor highlightCursor(document);
// clear formatting !
highlightCursor.setPosition(document->characterCount() - 1, QTextCursor::KeepAnchor);
highlightCursor.mergeCharFormat(QTextCharFormat());
highlightCursor.setPosition(0, QTextCursor::MoveAnchor);
if (!searchString.isEmpty())
{
QTextCharFormat colorFormat = highlightCursor.charFormat();
colorFormat.setFontLetterSpacing(110);
colorFormat.setForeground(Qt::black);
colorFormat.setFontWeight(QFont::Bold);
colorFormat.setBackground(Qt::gray);
while (!highlightCursor.isNull() && !highlightCursor.atEnd())
{
highlightCursor = document->find(searchString, highlightCursor);
if (!highlightCursor.isNull())
{
highlightCursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor);
highlightCursor.mergeCharFormat(colorFormat);
}
}
}
}
void MainWindow::on_checkBoxWrapText_toggled(bool checked)
{
if (checked)
ui->textBrowserLogs->setLineWrapMode(QPlainTextEdit::LineWrapMode::WidgetWidth);
else
ui->textBrowserLogs->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap);
}
void MainWindow::on_checkBoxEnableTracer_toggled(bool checked)
{
if (checked)
{
createChartTracer();
connect(ui->widgetChart, SIGNAL(mouseMove(QMouseEvent *)), this, SLOT(on_tracerShowPointValue(QMouseEvent *)));
}
else
{
disconnect(ui->widgetChart, SIGNAL(mouseMove(QMouseEvent *)), this, SLOT(on_tracerShowPointValue(QMouseEvent *)));
delete phaseTracer;
phaseTracer = nullptr;
}
ui->widgetChart->replot();
}
void MainWindow::createChartTracer()
{
// add the phase tracer (red circle) which sticks to the graph data:
this->phaseTracer = new QCPItemTracer(ui->widgetChart);
this->phaseTracer->setInterpolating(false);
if (ui->comboBoxTracerStyle->currentText().contains("Crosshair", Qt::CaseSensitivity::CaseInsensitive))
this->phaseTracer->setStyle(QCPItemTracer::tsCrosshair);
else
this->phaseTracer->setStyle(QCPItemTracer::tsCircle);
this->phaseTracer->setPen(QPen(Qt::red));
this->phaseTracer->setBrush(Qt::red);
this->phaseTracer->setSize(8);
}
void MainWindow::on_pushButtonClearAll_clicked()
{
ui->widgetChart->xAxis->setRange(-1.0, ui->spinBoxScrollingTimeRange->value());
ui->widgetChart->yAxis->setRange(-1.0, 1.0);
parser.restartChartTimer();
parser.clearExternalClock();
clearGraphs(true);
ui->tableWidgetParsedData->clearContents();
ui->tableWidgetParsedData->setRowCount(0);
ui->tableWidgetLogTable->setRowCount(0);
ui->tableWidgetLogTable->setColumnCount(1);
if (ui->checkBoxRAMClearChart->isChecked())
parser.clearStorage();
}
void MainWindow::on_pushButtonEnablePlot_toggled(bool checked)
{
if (checked)
ui->pushButtonEnablePlot->setText("Enable");
else
ui->pushButtonEnablePlot->setText("Disable");
}
void MainWindow::on_pushButtonSend_clicked()
{
if (ui->comboBoxSend->findText(ui->comboBoxSend->currentText()) < 0)
ui->comboBoxSend->addItem(ui->comboBoxSend->currentText()); // add to history (here we have to do it manually)
on_comboBoxSendReturnPressedSlot();
}
void MainWindow::on_pushButtonClearHistory_clicked()
{
ui->comboBoxSend->clear();
}
void MainWindow::on_pushButtonClearGraphs_clicked()
{
clearGraphData(true);
}
void MainWindow::on_lineEditCustomParsingRules_editingFinished()
{
ui->lineEditCustomParsingRules->setText(ui->lineEditCustomParsingRules->text().replace(" || ", " "));
ui->lineEditCustomParsingRules->setText(ui->lineEditCustomParsingRules->text().simplified().replace(" ", " || "));
clearGraphs(true);
loadFromRAM(false);
}
void MainWindow::on_spinBoxMaxGraphs_valueChanged(int arg1)
{
QPalette *paletteRed = new QPalette();
paletteRed->setColor(QPalette::Text, Qt::GlobalColor::red);
if (arg1 > 10)
ui->spinBoxMaxGraphs->setPalette(*paletteRed);
else
ui->spinBoxMaxGraphs->setPalette(QPalette());
this->clearGraphs(false);
this->loadFromRAM(false);
ui->widgetChart->replot();
}
void MainWindow::on_spinBoxMaxLines_valueChanged(int arg1)
{
ui->textBrowserLogs->document()->setMaximumBlockCount(arg1);
}
void MainWindow::on_checkBoxAutoTrack_toggled(bool checked)
{
if (checked)
{
ui->spinBoxScrollingTimeRange->setEnabled(true);
ui->checkBoxAutoRescaleY->setEnabled(true);
}
else
{
ui->spinBoxScrollingTimeRange->setEnabled(false);
ui->checkBoxAutoRescaleY->setEnabled(false);
}
}
void MainWindow::on_spinBoxProcessingDelay_valueChanged(int arg1)
{
int newInterval = qMax(1, arg1); // Never 0 ! Couses CPU run like crazy !
serialStringProcessingTimer->setInterval(newInterval);
udpStringProcessingTimer->setInterval(newInterval);
QPalette *paletteRed = new QPalette();
paletteRed->setColor(QPalette::Text, Qt::GlobalColor::red);
if (newInterval > ui->spinBoxProcessingDelay->minimum())
ui->spinBoxProcessingDelay->setPalette(*paletteRed);
else
ui->spinBoxProcessingDelay->setPalette(QPalette());
}
void MainWindow::on_comboBoxTracerStyle_currentIndexChanged(const QString &arg1)
{
if (ui->checkBoxEnableTracer->isChecked())
{
if (phaseTracer != nullptr)
{
disconnect(ui->widgetChart, SIGNAL(mouseMove(QMouseEvent *)), this, SLOT(on_tracerShowPointValue(QMouseEvent *)));
delete phaseTracer;
phaseTracer = nullptr;
}
createChartTracer();
connect(ui->widgetChart, SIGNAL(mouseMove(QMouseEvent *)), this, SLOT(on_tracerShowPointValue(QMouseEvent *)));
ui->widgetChart->replot();
}
}
void MainWindow::on_pushButtonSerialConnect_toggled(bool checked)
{
bool inputError = false;
if (checked)
{
if (serial.getAvailiblePorts().count() < 1)
{
addLog("App >>\t No devices available", true);
addLog("App >>\t Unable to open serial port!", true);
ui->pushButtonSerialConnect->setChecked(false);
inputError = true;
}
if (ui->comboBoxBaudRates->currentText().toInt() == 0)
{
addLog("App >>\t Invalid baud rate!", true);
inputError = true;
}
if (inputError)
return;
QString parsedPortName = QSerialPortInfo::availablePorts().at(ui->comboBoxDevices->currentIndex()).portName();
uint parsedBaudRate = ui->comboBoxBaudRates->currentText().toInt();
QString dataBits = ui->comboBoxDataBits->currentText();
QString stopBits = ui->comboBoxStopBits->currentText();
QString parity = ui->comboBoxParity->currentText();
QString flowControl = ui->comboBoxFlowControl->currentText();
if (serial.begin(parsedPortName, parsedBaudRate, dataBits, parity, stopBits, flowControl, ui->checkBoxDTR->isChecked()))
{
serialStringProcessingTimer->start(ui->spinBoxProcessingDelay->value());
parser.restartChartTimer();
if (ui->pushButtonLogging->isChecked() && fileLogger.isOpen() == false) // logger on standby ?
fileLogger.beginLog(ui->lineEditSaveLogPath->text(), ui->checkBoxAutoLogging->isChecked(), ui->lineEditSaveFileName->text(), ui->checkBoxTruncateFileOnSave->isChecked());
connect(serialStringProcessingTimer, SIGNAL(timeout()), this, SLOT(on_processSerial()));
addLog("App >>\t Serial port opened. " + serial.getSerialInfo() + " DTR: " + QString::number(ui->checkBoxDTR->isChecked()), true);
ui->pushButtonSerialConnect->setText("Disconnect");
}
else
{
ui->pushButtonSerialConnect->setChecked(false);
addLog("App >>\t Unable to open serial port!", true);
}
}
else
{
serialStringProcessingTimer->stop();
disconnect(serialStringProcessingTimer, SIGNAL(timeout()), this, SLOT(on_processSerial()));
if (serial.end())
{
addLog("App >>\t Connection closed.", true);
ui->pushButtonSerialConnect->setText("Connect");
}
else
{
ui->pushButtonSerialConnect->setChecked(true);
addLog("App >>\t ERROR: Unable to close cennection !", true);
}
if (!ui->pushButtonSerialConnect->isChecked() && !ui->pushButtonUDPConnect->isChecked())
{
fileLogger.closeFile();
}
}
}
void MainWindow::on_actionSave_As_triggered()
{
qDebug() << "Click save file !";
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Log"), "", tr("(*.txt);;All Files (*)"));
if (fileName.isEmpty())
{
addLog("App >>\t Saving file aborted - filename not specified.", true);
return;
}
else
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
QMessageBox::information(this, tr("Unable to open file"), file.errorString());
return;
}
QTextStream out(&file);
out << ui->textBrowserLogs->toPlainText();
}
}
void MainWindow::on_actionFull_chart_triggered()
{
ui->splitterReceivedData->setSizes(QList<int>({0, this->width()}));
}
void MainWindow::on_actionFull_text_view_triggered()
{
ui->splitterReceivedData->setSizes(QList<int>({this->width(), 0}));
}
void MainWindow::on_action50_50_view_triggered()
{
ui->splitterReceivedData->setSizes(QList<int>({this->width() / 2, this->width() / 2}));
}
void MainWindow::on_actionWhat_s_new_triggered()
{
on_printIntroChangelog();
}
void MainWindow::on_actionQuit_triggered()
{
this->close();
}
void MainWindow::on_actionPlotter_triggered()
{
ui->stackedWidgetGraphView->setCurrentIndex(0);
}
void MainWindow::on_action3D_orientation_triggered()
{
// ui->stackedWidget->setCurrentIndex(1); // WIP
}
void MainWindow::on_printPlot(QPrinter *printer)
{
printer->setPageSize(QPrinter::PageSize::A4);
QCPPainter painter(printer);
QRectF pageRect = printer->pageRect(QPrinter::DevicePixel);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, true);
int plotWidth = ui->widgetChart->viewport().width(), plotHeight = ui->widgetChart->viewport().height();
double scale = pageRect.width() / (float)plotWidth;
painter.setMode(QCPPainter::pmNoCaching);
painter.scale(scale, scale);
ui->widgetChart->toPainter(&painter, plotWidth, plotHeight);
}
void MainWindow::on_printLog(QPrinter *printer)
{
ui->textBrowserLogs->print(printer);
}
void MainWindow::on_checkBoxShowLegend_toggled(bool checked)
{
ui->widgetChart->legend->setVisible(checked);
ui->widgetChart->replot();
}
void MainWindow::on_actionSave_graph_as_triggered()
{
}
void MainWindow::on_actionPrint_Graph_triggered()
{
QPrinter chartPrinter;
chartPrinter.setFullPage(true);
QPrintPreviewDialog previewDialog(&chartPrinter);
previewDialog.setWindowFlags(Qt::Window);
connect(&previewDialog, SIGNAL(paintRequested(QPrinter *)), SLOT(on_printPlot(QPrinter *)));
previewDialog.exec();
}
void MainWindow::on_actionPrint_log_triggered()
{
QPrinter logPrinter;
QPrintPreviewDialog previewLogDialog(&logPrinter);
previewLogDialog.setWindowFlags(Qt::Window);
connect(&previewLogDialog, SIGNAL(paintRequested(QPrinter *)), SLOT(on_printLog(QPrinter *)));
previewLogDialog.exec();
}
void MainWindow::on_pushButtonUDPConnect_toggled(bool checked)
{
if (checked)
{
bool status = false;
if (ui->comboBoxUDPReceiveMode->currentText().contains("LocalHost"))
{
status = networkUDP.begin(QHostAddress::LocalHost, ui->spinBoxUDPReceivePort->value());
}
else if (ui->comboBoxUDPReceiveMode->currentText().contains("Any"))
{
status = networkUDP.begin(QHostAddress::Any, ui->spinBoxUDPReceivePort->value());
}
else if (ui->comboBoxUDPReceiveMode->currentText().contains("SpecialAddress"))
{
status = networkUDP.begin(QHostAddress(ui->lineEditUDPTargetIP->text()), ui->spinBoxUDPReceivePort->value());
}
if (status == true)
{
udpStringProcessingTimer->start(ui->spinBoxProcessingDelay->value());
parser.restartChartTimer();
if (ui->pushButtonLogging->isChecked() && fileLogger.isOpen() == false)
fileLogger.beginLog(ui->lineEditSaveLogPath->text(), ui->checkBoxAutoLogging->isChecked(), ui->lineEditSaveFileName->text(), ui->checkBoxTruncateFileOnSave->isChecked());
connect(udpStringProcessingTimer, SIGNAL(timeout()), this, SLOT(on_processUDP()));
addLog("App >>\t UDP port opened.", true);
ui->pushButtonUDPConnect->setText("Close Connection");
}
else
{
addLog("App >>\t UDP error. Unable to bind", true);
}
}
else
{
if (networkUDP.end())
{
udpStringProcessingTimer->stop();
addLog("App >>\t UDP port closed.", true);
disconnect(udpStringProcessingTimer, SIGNAL(timeout()), this, SLOT(on_processUDP()));
if (!ui->pushButtonSerialConnect->isChecked() && !ui->pushButtonUDPConnect->isChecked())
fileLogger.closeFile();
ui->pushButtonUDPConnect->setText("Open Connection");
}
}
}
void MainWindow::on_comboBoxUDPSendMode_currentIndexChanged(const QString &arg1)
{
if (arg1.contains("SpecialAddress") || ui->comboBoxUDPReceiveMode->currentText().contains("SpecialAddress"))
ui->lineEditUDPTargetIP->setEnabled(true);
else
ui->lineEditUDPTargetIP->setEnabled(false);
}
void MainWindow::on_comboBoxUDPReceiveMode_currentIndexChanged(const QString &arg1)
{
if (ui->pushButtonUDPConnect->isChecked() == true)
{
if (ui->comboBoxUDPReceiveMode->currentText().contains("LocalHost"))
{
networkUDP.bind(QHostAddress::LocalHost, ui->spinBoxUDPReceivePort->value());
}
else if (ui->comboBoxUDPReceiveMode->currentText().contains("Any"))
{
networkUDP.bind(QHostAddress::Any, ui->spinBoxUDPReceivePort->value());
}
else if (ui->comboBoxUDPReceiveMode->currentText().contains("SpecialAddress"))
{
networkUDP.bind(QHostAddress(ui->lineEditUDPTargetIP->text()), ui->spinBoxUDPReceivePort->value());
}
}
if (arg1.contains("SpecialAddress") || ui->comboBoxUDPSendMode->currentText().contains("SpecialAddress"))
ui->lineEditUDPTargetIP->setEnabled(true);
else
ui->lineEditUDPTargetIP->setEnabled(false);
}
void MainWindow::on_pushButtonLogging_toggled(bool checked)
{
if (checked)
{
if (ui->checkBoxAutoLogging->isChecked() == false && ui->lineEditSaveFileName->text().isEmpty())
{
addLog("App >>\t logger error - filename not specified !", true);
ui->pushButtonLogging->setChecked(false);
return;
}
if (ui->pushButtonSerialConnect->isChecked() || ui->pushButtonUDPConnect->isChecked())
{
if (!fileLogger.beginLog(ui->lineEditSaveLogPath->text(), ui->checkBoxAutoLogging->isChecked(), ui->lineEditSaveFileName->text()), ui->checkBoxTruncateFileOnSave->isChecked())
{
addLog("App >>\t logger error - unable to open File", true);
ui->pushButtonLogging->setChecked(false);
return;
}
}
ui->comboBoxLogFormat->setEnabled(false);
ui->pushButtonLogging->setText("Disable Logging");
}
else
{
ui->comboBoxLogFormat->setEnabled(true);
ui->pushButtonLogging->setText("Enable Logging");
fileLogger.closeFile();
}
}
void MainWindow::on_checkBoxAutoLogging_toggled(bool checked)
{
if (checked)
{
ui->pushButtonLogging->setEnabled(false);
ui->lineEditSaveFileName->setEnabled(false);
ui->pushButtonAddDateTime->setEnabled(false);
ui->comboBoxLogFormat->setEnabled(false);
ui->lineEditSaveFileName->setText("%DateTime%_Log" + ui->comboBoxLogFormat->currentText());
ui->pushButtonLogging->setChecked(true); // Trigger begin log
ui->pushButtonLogging->setText("Auto");
}
else
{
ui->pushButtonLogging->setEnabled(true);
ui->lineEditSaveFileName->setEnabled(true);
ui->pushButtonAddDateTime->setEnabled(true);
ui->pushButtonLogging->setChecked(false);
ui->pushButtonLogging->setText("Enable Logging");
ui->lineEditSaveFileName->clear();
ui->comboBoxLogFormat->setEnabled(true);
}
}
void MainWindow::on_pushButtonSetDefaultLogPath_clicked()
{
ui->lineEditSaveLogPath->setText(qApp->applicationDirPath() + "/Logs");
}
void MainWindow::on_pushButtonAddDateTime_clicked()
{
ui->lineEditSaveFileName->setText(QDateTime::currentDateTime().toString("dd.MM.yyyy_hh:mm:ss:zzz_") + ui->lineEditSaveFileName->text());
}
void MainWindow::on_pushButtonLogPath_clicked()
{
QString newPath;
if (QDir(ui->lineEditSaveLogPath->text()).isReadable())
newPath = QFileDialog::getExistingDirectory(this, "Set log path:", ui->lineEditSaveLogPath->text());
else
newPath = QFileDialog::getExistingDirectory(this, "Set log path:", QDir::homePath());
if (newPath.isEmpty() == false)
ui->lineEditSaveLogPath->setText(newPath);
}
void MainWindow::on_comboBoxSerialReadMode_currentIndexChanged(int index)
{
serial.setReadMode(index);
}
void MainWindow::on_actionAbout_Qt_triggered()
{
qApp->aboutQt();
}
void MainWindow::on_pushButtonClearTable_clicked()
{
ui->tableWidgetParsedData->clearContents();
ui->tableWidgetParsedData->setRowCount(0);
}
void MainWindow::on_tableWidgetParsedData_customContextMenuRequested(const QPoint &pos)
{
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WidgetAttribute::WA_DeleteOnClose);
menu->addAction("Apply to custom display", this, [=]()
{ emit on_pushButtonSetSelectedToGraph_clicked(); }); // C++ lambda expression
menu->addAction("Copy as text", this, [=]()
{
QString copyText;
foreach (auto item, ui->tableWidgetParsedData->selectedItems())
copyText.append(item->text() + " ");
QApplication::clipboard()->setText(copyText);
}); // C++ lambda expression
menu->addAction("Set as clock label", this, [=]()
{ ui->lineEditExternalClockLabel->setText(ui->tableWidgetParsedData->selectedItems().first()->text()); }); // C++ lambda expression
menu->addAction("Clear table contents", this, [=]()
{
ui->tableWidgetParsedData->clearContents();
ui->tableWidgetParsedData->setRowCount(0);
}); // C++ lambda expression
menu->popup(ui->tableWidgetParsedData->mapToGlobal(pos));
}
void MainWindow::on_pushButtonSetSelectedToGraph_clicked()
{
QStringList tableLabels;
for (auto i = 0; i < ui->tableWidgetParsedData->rowCount(); ++i)
{
if (ui->tableWidgetParsedData->item(i, 0)->isSelected())
tableLabels.append(ui->tableWidgetParsedData->item(i, 0)->text());
}
// clearGraphs(true);
if (ui->spinBoxMaxGraphs->value() < tableLabels.count())
ui->spinBoxMaxGraphs->setValue(tableLabels.count());
on_setSelectedLabels(&tableLabels);
}
void MainWindow::on_toolButtonAdvancedGraphMenu_clicked()
{
if (ui->toolButtonAdvancedGraphMenu->arrowType() == Qt::ArrowType::DownArrow)
{
ui->splitterGraphTable->setSizes({ui->groupBoxLog->height(), 0});
ui->toolButtonAdvancedGraphMenu->setArrowType(Qt::ArrowType::UpArrow);
}
else
{
ui->splitterGraphTable->setSizes({static_cast<int>(ui->groupBoxLog->height() * 0.75), static_cast<int>(ui->groupBoxLog->height() * 0.25)});
ui->toolButtonAdvancedGraphMenu->setArrowType(Qt::ArrowType::DownArrow);
}
}
void MainWindow::on_splitterGraphTable_splitterMoved(int pos, int index)
{
if (pos < ui->splitterGraphTable->height() - 30)
ui->toolButtonAdvancedGraphMenu->setArrowType(Qt::ArrowType::DownArrow);
else
ui->toolButtonAdvancedGraphMenu->setArrowType(Qt::ArrowType::UpArrow);
}
void MainWindow::on_pushButtonTextLogToggle_toggled(bool checked)
{
if (checked)
{
ui->pushButtonTextLogToggle->setText("Enable");
}
else
{
ui->pushButtonTextLogToggle->setText("Disable");
}
}
void MainWindow::on_lineEditExternalClockLabel_editingFinished()
{
ui->lineEditExternalClockLabel->setText(ui->lineEditExternalClockLabel->text().simplified());
}
void MainWindow::on_pushButtonLoadPath_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Log File:"), "",
tr("(*.txt *.csv);;All Files (*)"));
ui->lineEditLoadFilePath->setText(fileName);
QFile file(fileName);
if (!file.exists())
{
ui->lineEditFileInfo->setText("File doesnt exist !");
return;
}
QList<QTime> timeRange = fileReader.getFileTimeRange(&file);
ui->timeEditMinParsingTime->setTime(timeRange.first());
ui->timeEditMaxParsingTime->setTime(timeRange.last());
QString info = "Size: " + QString::number(file.size());
ui->lineEditFileInfo->setText(info);
}
void MainWindow::on_processLoadedFileLine(QString *line, int *progressPercent)
{
parser.parse(*line, true, true, ""); // Parse string - split into labels + numeric data
QStringList labelList = parser.getStringListLabels();
QList<double> numericDataList = parser.getListNumericValues();
QList<long> timeStampList = parser.getListTimeStamp();
this->processChart(labelList, numericDataList, timeStampList);
this->processTable(labelList, numericDataList); // Fill tableWidget
// this->saveToRAM(labelList, numericDataList, timeStampList);
// addLog(line);
ui->progressBarLoadFile->setValue(*progressPercent);
}
void MainWindow::on_updateProgressBar(float *percent)
{
ui->progressBarLoadFile->setValue(*percent);
}
void MainWindow::on_processLoadedFile(QString *text)
{
disconnect(&fileReader, SIGNAL(textReady(QString *)), this, SLOT(on_processLoadedFile(QString *)));
connect(&parser, SIGNAL(updateProgress(float *)), this, SLOT(on_updateProgressBar(float *)));
parser.setReportProgress(true);
parser.clearStorage();
parser.setParsingTimeRange(ui->timeEditMinParsingTime->time(), ui->timeEditMaxParsingTime->time());
// Select file type
if (ui->comboBoxLogFormat->currentIndex() == 0)
parser.parseCSV(*text, (bool)ui->comboBoxClockSource->currentIndex() == 1, ui->lineEditExternalClockLabel->text());
else
parser.parse(*text, false, true, "");
// disconnect events, reset parser
parser.resetTimeRange();
parser.setReportProgress(false);
disconnect(&parser, SIGNAL(updateProgress(float *)), this, SLOT(on_updateProgressBar(float *)));
// Parsing
{
QStringList labelList = parser.getStringListLabels();
QList<double> numericDataList = parser.getListNumericValues();
QList<long> timeStampList = parser.getListTimeStamp();
this->processChart(labelList, numericDataList, timeStampList);
this->processTable(labelList, numericDataList);
this->saveToRAM(labelList, numericDataList, timeStampList);
}
// Add text to log
{
if (ui->checkBoxAppendLoadedTextToLog->isChecked() == true)
this->ui->textBrowserLogs->appendPlainText(*text);
}
}
void MainWindow::on_pushButtonLoadRAMBuffer_clicked()
{
if (ui->checkBoxRAMClearChart->isChecked())
this->clearGraphData(false);
loadFromRAM((bool)ui->comboBoxRAMLoadMode->currentIndex());
}
void MainWindow::on_pushButtonRAMClear_clicked()
{
parser.clearStorage();
}
void MainWindow::on_pushButtonLoadFile_clicked()
{
ui->progressBarLoadFile->setValue(0);
if (ui->pushButtonLoadFile->text().contains("Load"))
{
this->clearGraphs(true);
ui->pushButtonLoadFile->setText("Cancel");
if (QDir(ui->lineEditLoadFilePath->text().trimmed()).isReadable())
{
QFile inputFile(ui->lineEditLoadFilePath->text().trimmed());
connect(&fileReader, SIGNAL(textReady(QString *)), this, SLOT(on_processLoadedFile(QString *)));
connect(&fileReader, &FileReader::fileReadFinished, this, [=]()
{
ui->pushButtonLoadFile->setText("Load File");
ui->progressBarLoadFile->setValue(100);
});
if (fileReader.readAllAtOnce(&inputFile))
{
addLog("App >>\t Read file succesfully... ", true);
}
else
{
addLog("App >>\t Error - invalid file !", true);
ui->pushButtonLoadFile->setText("Load File");
ui->progressBarLoadFile->setValue(0);
}
}
else
{
addLog("App >>\t Error - invalid file path !", true);
ui->pushButtonLoadFile->setText("Load File");
ui->progressBarLoadFile->setValue(0);
}
}
else
{
parser.abort();
disconnect(&fileReader, SIGNAL(textReady(QString *)), this, SLOT(on_processLoadedFile(QString *)));
ui->pushButtonLoadFile->setText("Load File");
ui->progressBarLoadFile->setValue(0);
}
}
void MainWindow::on_lineEditLoadFilePath_customContextMenuRequested(const QPoint &pos)
{
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WidgetAttribute::WA_DeleteOnClose);
menu->addAction("Open file", this, [=]()
{ QDesktopServices::openUrl(QUrl(ui->lineEditLoadFilePath->text())); }); // C++ lambda expression
menu->addAction("Open folder", this, [=]()
{ QDesktopServices::openUrl(QUrl(QDir(QFileInfo(ui->lineEditLoadFilePath->text()).absoluteDir()).absolutePath())); }); // C++ lambda expression
menu->popup(ui->lineEditLoadFilePath->mapToGlobal(pos));
}
void MainWindow::on_pushButtonSaveRAMBuffer_clicked()
{
//QStringList newlabelList, QList<double> newDataList, QList<long> newTimeList, QString text)
QStringList newlabelList;
QList<double> newDataList;
QList<long> newTimeList;
QString text = "";
for (auto i = 0; i < ui->widgetChart->graphCount(); ++i)
{
newlabelList.append(ui->widgetChart->graph(i)->name());
QCPGraphDataContainer::const_iterator begin = ui->widgetChart->graph(i)->data()->at(ui->widgetChart->graph(i)->data()->dataRange().begin()); // get range begin iterator from index
QCPGraphDataContainer::const_iterator end = ui->widgetChart->graph(i)->data()->at(ui->widgetChart->graph(i)->data()->dataRange().end()); // get range end iterator from index
for (QCPGraphDataContainer::const_iterator it = begin; it != end; ++it)
{
newTimeList.append(it->key);
newDataList.append(it->value);
}
}
if (ui->comboBoxRAMSaveMode->currentIndex() == 1)
text.append(ui->textBrowserLogs->toPlainText());
parser.appendSetToMemory(newlabelList, newDataList, newTimeList, text);
}
void MainWindow::on_actionInfo_triggered()
{
// infoDialog.setModal(true);
infoDialog.show();
}
void MainWindow::on_comboBoxLoggingMode_currentIndexChanged(int index)
{
if (index == 0)
ui->checkBoxSimplifyLog->setEnabled(true);
else if (index == 1)
ui->checkBoxSimplifyLog->setEnabled(false);
}
void MainWindow::on_actionWhats_this_triggered()
{
QWhatsThis::enterWhatsThisMode();
}
void MainWindow::on_lineEditSaveFileName_editingFinished()
{
if (ui->comboBoxLogFormat->currentText() == ".txt")
{
if (ui->lineEditSaveFileName->text().endsWith(".txt") == false)
ui->lineEditSaveFileName->setText(ui->lineEditSaveFileName->text().append(".txt")); // auto-complete filename with .txt extension
}
else if (ui->comboBoxLogFormat->currentText() == ".csv")
{
if (ui->lineEditSaveFileName->text().endsWith(".csv") == false)
ui->lineEditSaveFileName->setText(ui->lineEditSaveFileName->text().append(".csv")); // auto-complete filename with .txt extension
}
}
void MainWindow::on_checkBoxAutoSaveBuffer_toggled(bool checked)
{
parser.clearStorage();
ui->pushButtonSaveParserMemory->setEnabled(!checked);
}
void MainWindow::on_comboBoxClockSource_currentIndexChanged(int index)
{
if (index == 1)
{
ui->lineEditExternalClockLabel->setEnabled(true);
ui->comboBoxExternalTimeFormat->setEnabled(true);
}
else
{
ui->lineEditExternalClockLabel->setEnabled(false);
ui->comboBoxExternalTimeFormat->setEnabled(false);
}
}
void MainWindow::on_comboBoxFormat_currentIndexChanged(int index)
{
if (index == 0)
ui->comboBoxTextProcessing->setEnabled(true);
else
ui->comboBoxTextProcessing->setEnabled(false);
}
void MainWindow::on_toolButtonHideTable_clicked()
{
ui->splitterGraphTable->setSizes({ui->splitterGraphTable->width(), 0});
ui->toolButtonAdvancedGraphMenu->setArrowType(Qt::ArrowType::UpArrow);
}
void MainWindow::on_comboBoxAddTextMode_currentIndexChanged(int index)
{
// if (index == 1)
// {
// ui->radioButtonScrollToButtom->setCheckable(false);
// ui->radioButtonScrollToButtom->setChecked(false);
// }
// else
// {
// ui->radioButtonScrollToButtom->setCheckable(true);
// }
}
void MainWindow::on_actionHide_parser_data_triggered()
{
ui->splitterGraphTable->setSizes({ui->splitterGraphTable->width(), 0});
}
void MainWindow::on_actionShow_parser_data_triggered()
{
ui->splitterGraphTable->setSizes({ui->splitterGraphTable->width(), ui->splitterGraphTable->height() / 2});
}
void MainWindow::on_radioButtonScrollToButtom_clicked()
{
ui->textBrowserLogs->verticalScrollBar()->setValue(ui->textBrowserLogs->verticalScrollBar()->maximum());
}
void MainWindow::on_comboBoxLogFormat_currentIndexChanged(int index)
{
ui->comboBoxLoggingMode->setEnabled((bool)index);
ui->checkBoxSimplifyLog->setEnabled((bool)index);
// ui->pushButtonLoadFile->setEnabled((bool)index);
if (ui->comboBoxLogFormat->currentText().contains("txt"))
ui->lineEditSaveFileName->setText(ui->lineEditSaveFileName->text().replace("csv", "txt"));
else if (ui->comboBoxLogFormat->currentText().contains("csv"))
ui->lineEditSaveFileName->setText(ui->lineEditSaveFileName->text().replace("txt", "csv"));
}
void MainWindow::on_comboBoxGraphDisplayMode_currentIndexChanged(int index)
{
clearGraphs(true);
loadFromRAM(0);
QPalette *paletteRed = new QPalette();
paletteRed->setColor(QPalette::Text, Qt::GlobalColor::red);
if (index == 0)
{
ui->lineEditCustomParsingRules->setEnabled(false);
ui->labelParsingRules->setEnabled(false);
ui->comboBoxGraphDisplayMode->setPalette(QPalette()); // Empty = default (OS specific !)
}
else
{
ui->lineEditCustomParsingRules->setEnabled(true);
ui->labelParsingRules->setEnabled(true);
ui->comboBoxGraphDisplayMode->setPalette(*paletteRed);
}
}
void MainWindow::on_pushButtonClearLogTable_clicked()
{
ui->tableWidgetLogTable->setRowCount(0);
ui->tableWidgetLogTable->setColumnCount(1);
}
void MainWindow::on_checkBoxScrollLogEnableSorting_toggled(bool checked)
{
ui->tableWidgetLogTable->setSortingEnabled(checked);
}
// https://stackoverflow.com/questions/27353026/qtableview-output-save-as-csv-or-txt
void MainWindow::exportTableLogToCSV(QTableView *table, QChar sep)
{
QString filters("CSV files (*.csv);;All files (*.*)");
QString defaultFilter("CSV files (*.csv)");
QString fileName = QFileDialog::getSaveFileName(0, "Save file", QCoreApplication::applicationDirPath(),
filters, &defaultFilter);
QFile file(fileName);
QAbstractItemModel *model = table->model();
if (file.open(QFile::WriteOnly | QFile::Truncate))
{
QTextStream data(&file);
QStringList strList;
for (int i = 0; i < model->columnCount(); ++i)
{
if (model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString().length() > 0)
strList.append("\"" + model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString() + "\"");
else
strList.append("");
}
data << strList.join(sep) << "\n";
for (int i = 0; i < model->rowCount(); ++i)
{
strList.clear();
for (int j = 0; j < model->columnCount(); ++j)
{
if (model->data(model->index(i, j)).toString().length() > 0)
strList.append("\"" + model->data(model->index(i, j)).toString() + "\"");
else
strList.append("");
}
data << strList.join(sep) + "\n";
}
file.close();
}
}
void MainWindow::exportArraysToCSV(QStringList labelList, QList<QList<double>> dataColums, QChar sep)
{
QString filters("CSV files (*.csv);;All files (*.*)");
QString defaultFilter("CSV files (*.csv)");
QString fileName = QFileDialog::getSaveFileName(0, "Save file", QCoreApplication::applicationDirPath(),
filters, &defaultFilter);
QFile file(fileName);
if (file.open(QFile::WriteOnly | QFile::Truncate))
{
QTextStream data(&file);
QStringList strList;
foreach (auto label, labelList)
{
if (label.length() > 0)
strList.append("\"" + label + "\"");
else
strList.append("");
}
data << strList.join(sep) << "\n";
int maxRowCount = 0;
foreach (auto column, dataColums)
maxRowCount = qMax(maxRowCount, column.count());
for (int i = 0; i < maxRowCount; ++i) // rows
{
strList.clear();
for (int j = 0; j < dataColums.count(); ++j) // columns
{
if (i < dataColums[j].count())
strList.append(QString::number(dataColums[j][i], 'f'));
else
strList.append("\"\"");
}
data << strList.join(sep) + "\n";
}
file.close();
}
}
void MainWindow::on_pushButtonExportLogTableToCSV_clicked()
{
this->exportTableLogToCSV(ui->tableWidgetLogTable);
}
void MainWindow::on_pushButtonSerialLogScrollown_clicked()
{
ui->textBrowserLogs->verticalScrollBar()->setValue(ui->textBrowserLogs->verticalScrollBar()->maximum());
}
void MainWindow::on_pushButtonEnableTableLog_toggled(bool checked)
{
if (checked)
{
ui->pushButtonEnableTableLog->setChecked(true);
ui->pushButtonEnableTableLog->setText("Enable");
}
else
{
ui->pushButtonEnableTableLog->setChecked(false);
ui->pushButtonEnableTableLog->setText("Disable");
}
}
void MainWindow::on_lineEditLoadFilePath_textChanged(const QString &arg1)
{
QFile file(ui->lineEditLoadFilePath->text());
if (!file.exists())
{
ui->lineEditFileInfo->setText("File doesnt exist !");
return;
}
QList<QTime> timeRange = fileReader.getFileTimeRange(&file);
ui->timeEditMinParsingTime->setTime(timeRange.first());
ui->timeEditMaxParsingTime->setTime(timeRange.last());
QString info = "Size: " + QString::number(file.size());
ui->lineEditFileInfo->setText(info);
}
void MainWindow::on_actionFull_parser_data_triggered()
{
ui->splitterGraphTable->setSizes({0, ui->splitterGraphTable->height()});
}
void MainWindow::on_actionImage_triggered()
{
QString default_name = "export.png";
QString filename = QFileDialog::getSaveFileName(this, tr("Save File"), QDir::homePath() + "/" + default_name, tr("Image Files (*.png *.jpg *.bmp)"));
if (filename.isEmpty())
return;
QImage bitmap(ui->widgetChart->size(), QImage::Format_ARGB32_Premultiplied);
QPainter painter(&bitmap);
ui->widgetChart->render(&painter, QPoint(), QRegion(), QWidget::DrawChildren);
QImageWriter writer(filename, "png");
writer.write(bitmap);
qDebug() << "Wrote image to file";
}
//void MainWindow::on_actionto_csv_triggered()
//{
// // QStringList labelList = parser.getLabelStorage();
// // QStringList columnNames = labelList;
// // QList<QList<double>> columnsData;
// // QList<double> numericDataList = parser.getDataStorage();
// // columnNames.removeDuplicates();
// // for (auto i = 0; i < columnNames.count(); ++i)
// // {
// // columnsData.append(*new QList<double>);
// // while (labelList.contains(columnNames[i]))
// // {
// // columnsData[columnsData.count() - 1].append(numericDataList.takeAt(labelList.indexOf(columnNames[i])));
// // labelList.removeAt(labelList.indexOf(columnNames[i]));
// // }
// // }
//}
void MainWindow::on_actionto_csv_triggered()
{
QStringList columnNames;
QList<QList<double>> columnsData;
parser.getCSVReadyData(&columnNames, &columnsData);
this->exportArraysToCSV(columnNames, columnsData, ',');
}