... #include "cMainWindow.h" #include <QApplication> int main(int argc, char **argv) { QApplication app(argc, argv); cMainWindow *oMainWindow = new cMainWindow; oMainWindow->resize(400, 200); oMainWindow->show(); return app.exec(); } ...
... #pragma once #include <QMainWindow> #include "cActions.h" class QLabel; namespace Ui { class cMainWindow; } class cMainWindow : public QMainWindow { Q_OBJECT public: using sAction = cActions::sAction; public: explicit cMainWindow(QWidget *parent = 0); ~cMainWindow(); private slots: void on_actionHomePage_triggered(); void on_actionThemePage_triggered(); void onAction(const sAction &_action); private: Ui::cMainWindow *ui; QLabel *m_themeStatus; }; ...
... #include "cMainWindow.h" #include "ui_cMainWindow.h" #include <QStyleFactory> #include <QMessageBox> #include <QLabel> const QString ACTION_APPLY_STYLE = "ACTION_APPLY_STYLE"; cMainWindow::cMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::cMainWindow) { ui->setupUi(this); ui->stackedWidget->setCurrentWidget(ui->pageHome); ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); QStringList oThemes = QStyleFactory::keys(); for (const auto &oTheme : oThemes) { qDebug() << "La detection du style d'apparence a reussi." << "|theme=" << oTheme; ui->tableWidget->insertRow(ui->tableWidget->rowCount()); QTableWidgetItem *oTableWidgetItem = new QTableWidgetItem(oTheme); ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 0, oTableWidgetItem); cActions *oActions = new cActions; oActions->addAction(oTheme, ACTION_APPLY_STYLE, "Appliquer le style"); oActions->initActions(); connect(oActions, &cActions::emitAction, this, &cMainWindow::onAction); ui->tableWidget->setCellWidget(ui->tableWidget->rowCount() - 1, 1, oActions); } qDebug() << "La detection du style en cours est termine." << "|style=" << qApp->style()->name(); m_themeStatus = new QLabel; statusBar()->addWidget(m_themeStatus); m_themeStatus->setText(tr("Thème : %1").arg(qApp->style()->name())); } cMainWindow::~cMainWindow() { delete ui; } void cMainWindow::on_actionHomePage_triggered() { ui->stackedWidget->setCurrentWidget(ui->pageHome); } void cMainWindow::on_actionThemePage_triggered() { ui->stackedWidget->setCurrentWidget(ui->pageTheme); } void cMainWindow::onAction(const sAction &_action) { qDebug() << "L'action est en cours d'application." << "|data=" << _action.data << "|key=" << _action.key << "|text=" << _action.text; if (_action.key == ACTION_APPLY_STYLE) { qApp->setStyle(_action.data); m_themeStatus->setText(tr("Thème : %1").arg(qApp->style()->name())); } } ...
... #pragma once #include <QWidget> #include <QVector> #include <QMap> namespace Ui { class cActions; } class cActions : public QWidget { Q_OBJECT public: struct sAction { QString data; QString key; QString text; }; public: explicit cActions(QWidget *parent = 0); ~cActions(); void addAction(const QString &_data, const QString &_key, const QString &_text); void initActions(); private: bool isActive(const QString &_key) const; bool loadAction(const QString &_key, sAction &_action) const; private slots: void onAction(); signals: void emitAction(sAction); private: Ui::cActions *ui; QVector<sAction> m_actions; QMap<QAction *, QString> m_keys; }; ...
... #include "cActions.h" #include "ui_cActions.h" #include <QMenu> cActions::cActions(QWidget *parent) : QWidget(parent), ui(new Ui::cActions) { ui->setupUi(this); ui->layActions->setAlignment(Qt::AlignCenter); } cActions::~cActions() { delete ui; } void cActions::addAction(const QString &_data, const QString &_key, const QString &_text) { if (!isActive(_key)) { sAction oAction{_data, _key, _text}; m_actions.push_back(oAction); } else { qDebug() << "L'action a ete deja ajoutee a la liste." << "|data=" << _data << "|key=" << _key << "|text=" << _text; } } void cActions::initActions() { if (m_actions.isEmpty()) { qDebug() << "Aucune action n'a ete ajoutee à liste"; return; } QMenu *oMenu = new QMenu(this); for (const auto &oAction : m_actions) { QAction *iAction = new QAction(oAction.text); iAction->setData(oAction.data); connect(iAction, &QAction::triggered, this, &cActions::onAction); m_keys[iAction] = oAction.key; oMenu->addAction(iAction); } ui->btnActions->setMenu(oMenu); } bool cActions::isActive(const QString &_key) const { for (const auto &oAction : m_actions) { if (oAction.key == _key) { return true; } } return false; } bool cActions::loadAction(const QString &_key, sAction &_action) const { for (const auto &oAction : m_actions) { if (oAction.key == _key) { _action = oAction; return true; } } return false; } void cActions::onAction() { QAction *oAction = qobject_cast<QAction *>(sender()); QString oKey = m_keys[oAction]; sAction iAction; if (loadAction(oKey, iAction)) { emit emitAction(iAction); } } ...
... cmake_minimum_required(VERSION 3.10.0) project(rdvcpp VERSION 0.1.0 LANGUAGES C CXX) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_PREFIX_PATH "C:/Qt/6.5.2/msvc2019_64/lib/cmake") find_package(Qt6 REQUIRED COMPONENTS Widgets ) qt_wrap_ui(UI_FILES cMainWindow.ui cActions.ui ) add_executable(rdvcpp main.cpp cMainWindow.cpp cActions.cpp resources.qrc ${UI_FILES} ) target_link_libraries (rdvcpp Qt6::Widgets ) ...
... <RCC> <qresource prefix="/img"> <file alias="logo.png">data/img/logo.png</file> </qresource> </RCC> ...
... rdvcpp.exe ...
... #include "cMainWindow.h" #include <QApplication> #include <QFontDatabase> int main(int argc, char **argv) { QApplication app(argc, argv); QString oFontFile(":/font/fontawesome-webfont.ttf"); int id = QFontDatabase::addApplicationFont(oFontFile); if (id == -1) { qDebug() << "Le chargement de la police a echoue." << "|fontFile=" << oFontFile; } else { QStringList oFontFamilies = QFontDatabase::applicationFontFamilies(id); qDebug() << "Le chargement de la police a reussi." << "|fontFile=" << oFontFile << "|fontFamilies=" << oFontFamilies; } cMainWindow *oMainWindow = new cMainWindow; oMainWindow->resize(400, 200); oMainWindow->show(); return app.exec(); } ...
... #pragma once #include <QMainWindow> class cHelpWindow; namespace Ui { class cMainWindow; } class cMainWindow : public QMainWindow { Q_OBJECT public: explicit cMainWindow(QWidget *parent = 0); ~cMainWindow(); private slots: void on_actionHelpApp_triggered(); void on_actionAboutApp_triggered(); void on_actionAboutQt_triggered(); private: Ui::cMainWindow *ui; cHelpWindow *m_helpWindow; }; ...
... #include "cMainWindow.h" #include "ui_cMainWindow.h" #include "cHelpWindow.h" #include <QMessageBox> #include <QFile> #include <QFontDatabase> #include <QDebug> cMainWindow::cMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::cMainWindow) { ui->setupUi(this); QFile oFile(":/help/fr.html"); if (!oFile.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Le fichier d'aide est introuvable." << "filename=" << oFile.fileName(); return; } QByteArray oFileData = oFile.readAll(); m_helpWindow = new cHelpWindow(QString(oFileData), this); } cMainWindow::~cMainWindow() { delete ui; } void cMainWindow::on_actionHelpApp_triggered() { m_helpWindow->exec(); } void cMainWindow::on_actionAboutApp_triggered() { QMessageBox::about(this, "A propos de l'application ", "<b>ReadySCOPE - v1.0</b><br>" "Oscilloscope numérique<br><br>" "Produit par <a href='https://readydev.ovh/home'>ReadyDEV</a><br>" "Plateforme de Développement Continu"); } void cMainWindow::on_actionAboutQt_triggered() { QMessageBox::aboutQt(this); } ...
... #pragma once #include <QDialog> class cFloatButton; namespace Ui { class cHelpWindow; } class cHelpWindow : public QDialog { Q_OBJECT public: explicit cHelpWindow(const QString &_message, QWidget *parent = 0); ~cHelpWindow(); protected: void resizeEvent(QResizeEvent *event); private slots: void onOpenTopLink(); void onOpenBottomLink(); private: Ui::cHelpWindow *ui; QString m_message; cFloatButton *m_topLink; cFloatButton *m_bottomLink; }; ...
... #include "cHelpWindow.h" #include "ui_cHelpWindow.h" #include "cFloatButton.h" #include <QLabel> #include <QResizeEvent> #include <QScrollBar> using namespace std::chrono_literals; cHelpWindow::cHelpWindow(const QString &_message, QWidget *parent) : QDialog(parent), ui(new Ui::cHelpWindow), m_message(_message) { ui->setupUi(this); ui->txtHelp->setHtml(m_message); resize(600, 300); m_bottomLink = new cFloatButton(ICON_FA_CHEVRON_DOWN, this); connect(m_bottomLink, &cFloatButton::emitClicked, this, &cHelpWindow::onOpenBottomLink); m_topLink = new cFloatButton(ICON_FA_CHEVRON_UP, this); connect(m_topLink, &cFloatButton::emitClicked, this, &cHelpWindow::onOpenTopLink); } cHelpWindow::~cHelpWindow() { delete ui; } void cHelpWindow::resizeEvent(QResizeEvent *event) { m_bottomLink->move(width() - 75 - 50, height() - 85); m_topLink->move(width() - 75, height() - 85); } void cHelpWindow::onOpenTopLink() { QScrollBar *oScrollBar = ui->txtHelp->verticalScrollBar(); oScrollBar->setValue(0); } void cHelpWindow::onOpenBottomLink() { QScrollBar *oScrollBar = ui->txtHelp->verticalScrollBar(); oScrollBar->setValue(oScrollBar->maximum()); } ...
... #pragma once #include <QWidget> #include "IconsFontAwesome4.h" namespace Ui { class cFloatButton; } class cFloatButton : public QWidget { Q_OBJECT public: explicit cFloatButton(const QString &_iconLabel, QWidget *parent = 0); ~cFloatButton(); protected: bool eventFilter(QObject *object, QEvent *event); signals: void emitClicked(); private: Ui::cFloatButton *ui; QString m_iconLabel; }; ...
... #include "cFloatButton.h" #include "ui_cFloatButton.h" #include <QMouseEvent> using namespace std::chrono_literals; cFloatButton::cFloatButton(const QString &_iconLabel, QWidget *parent) : QWidget(parent), ui(new Ui::cFloatButton), m_iconLabel(_iconLabel) { ui->setupUi(this); adjustSize(); QFont font; font.setFamily("FontAwesome"); font.setPixelSize(20); ui->lblButton->setFont(font); ui->lblButton->setText(m_iconLabel); ui->lblButton->installEventFilter(this); } cFloatButton::~cFloatButton() { delete ui; } bool cFloatButton::eventFilter(QObject *object, QEvent *event) { if (object == ui->lblButton && event->type() == QEvent::MouseButtonRelease) { QMouseEvent *oMouseEvent = static_cast<QMouseEvent *>(event); if (oMouseEvent->button() == Qt::LeftButton) { emit emitClicked(); return true; } } return false; } ...
... cmake_minimum_required(VERSION 3.10.0) project(rdvcpp VERSION 0.1.0 LANGUAGES C CXX) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_PREFIX_PATH "C:/Qt/6.5.2/msvc2019_64/lib/cmake") find_package(Qt6 REQUIRED COMPONENTS Widgets ) qt_wrap_ui(UI_FILES cMainWindow.ui cHelpWindow.ui cFloatButton.ui ) add_executable(rdvcpp main.cpp cMainWindow.cpp cHelpWindow.cpp cFloatButton.cpp resources.qrc ${UI_FILES} ) target_link_libraries (rdvcpp Qt6::Widgets ) ...
... <RCC> <qresource prefix="/img"> <file alias="logo.png">data/img/logo.png</file> </qresource> <qresource prefix="/help"> <file alias="fr.html">data/help/fr.html</file> </qresource> <qresource prefix="/font"> <file alias="fontawesome-webfont.ttf">data/font/fontawesome-webfont.ttf</file> </qresource> </RCC> ...
... rdvcpp.exe ...
... #include "cMainWindow.h" #include <QApplication> int main(int argc, char **argv) { QApplication app(argc, argv); cMainWindow *oMainWindow = new cMainWindow; oMainWindow->resize(600, 400); oMainWindow->show(); return app.exec(); } ...
... #pragma once #include <QMainWindow> #include <QtSerialPort/QSerialPort> #include <QVector> #include <QMap> namespace Ui { class cMainWindow; } class cMainWindow : public QMainWindow { Q_OBJECT public: explicit cMainWindow(QWidget *parent = 0); ~cMainWindow(); private: bool isActive(const QString &_portName) const; void addConnection(const QString &_portName); void addPortToTab(const QString &_portName); bool loadConnection(const QString &_portName, QSerialPort **_serialPort) const; bool loadPortToTab(const QString &_portName, QWidget **_tabWidget) const; bool loadPortToTab(QWidget *_oTabWidget, QString &_portName) const; bool loadPortToTab(const QString &_portName, QLayout **_layout) const; void showSendMessageTab(const QString &_portName) const; void clearOpenConnection(); void clearSendMessagePort1(); void clearSendMessagePort2(); private slots: void on_actionOpenConnection_triggered(); void on_actionDisplayConnection_triggered(); void on_btnOpenConnection_clicked(); void on_btnSendMessagePort1_clicked(); void on_btnSendMessagePort2_clicked(); void onReadyData(); void onErrorOccurred(QSerialPort::SerialPortError error); void onSendMessage(QAction *_action); private: Ui::cMainWindow *ui; QVector<QSerialPort *> m_connections; QMap<QString, QWidget *> m_portToTab; }; ...
... #include "cMainWindow.h" #include "ui_cMainWindow.h" #include "cPortAction.h" #include "cMessageSend.h" #include "cMessageRecv.h" #include <QMessageBox> #include <QScrollBar> cMainWindow::cMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::cMainWindow) { ui->setupUi(this); ui->stackedWidget->setCurrentWidget(ui->pageHome); ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tabWidget->setCurrentWidget(ui->tabSendMessagePort1); ui->messageLayoutPort1->setAlignment(Qt::AlignTop); ui->messageLayoutPort2->setAlignment(Qt::AlignTop); } cMainWindow::~cMainWindow() { delete ui; } bool cMainWindow::isActive(const QString &_portName) const { for (QSerialPort *oSerialPort : m_connections) { if (oSerialPort->portName() == _portName) { if (oSerialPort->isOpen()) return true; } } return false; } void cMainWindow::addConnection(const QString &_portName) { ui->tableWidget->insertRow(ui->tableWidget->rowCount()); QTableWidgetItem *oTableWidgetItem = new QTableWidgetItem(_portName); ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 0, oTableWidgetItem); cPortAction *oPortAction = new cPortAction(_portName); connect(oPortAction, &cPortAction::emitSendMessage, this, &cMainWindow::onSendMessage); ui->tableWidget->setCellWidget(ui->tableWidget->rowCount() - 1, 1, oPortAction); } void cMainWindow::addPortToTab(const QString &_portName) { switch (m_portToTab.size()) { case 0: m_portToTab[_portName] = ui->tabSendMessagePort1; ui->tabWidget->setTabText(ui->tabWidget->indexOf(ui->tabSendMessagePort1), _portName); break; case 1: m_portToTab[_portName] = ui->tabSendMessagePort2; ui->tabWidget->setTabText(ui->tabWidget->indexOf(ui->tabSendMessagePort2), _portName); break; default: break; } } bool cMainWindow::loadConnection(const QString &_portName, QSerialPort **_serialPort) const { for (QSerialPort *oSerialPort : m_connections) { if (oSerialPort->portName() == _portName) { if (oSerialPort->isOpen()) { (*_serialPort) = oSerialPort; return true; } } } return false; } bool cMainWindow::loadPortToTab(const QString &_portName, QWidget **_tabWidget) const { QMap<QString, QWidget *>::const_iterator it; for (it = m_portToTab.begin(); it != m_portToTab.end(); ++it) { if (it.key() == _portName) { (*_tabWidget) = it.value(); return true; } } return false; } bool cMainWindow::loadPortToTab(QWidget *_oTabWidget, QString &_portName) const { QMap<QString, QWidget *>::const_iterator it; for (it = m_portToTab.begin(); it != m_portToTab.end(); ++it) { if (it.value() == _oTabWidget) { _portName = it.key(); return true; } } return false; } bool cMainWindow::loadPortToTab(const QString &_portName, QLayout **_layout) const { QWidget *oTabWidget; if (!loadPortToTab(_portName, &oTabWidget)) return false; if (oTabWidget == ui->tabSendMessagePort1) { (*_layout) = ui->messageLayoutPort1; return true; } if (oTabWidget == ui->tabSendMessagePort2) { (*_layout) = ui->messageLayoutPort2; return true; } return false; } void cMainWindow::showSendMessageTab(const QString &_portName) const { QWidget *oTabWidget; if (!loadPortToTab(_portName, &oTabWidget)) return; ui->tabWidget->setTabVisible(ui->tabWidget->indexOf(ui->tabSendMessagePort1), (oTabWidget == ui->tabSendMessagePort1)); ui->tabWidget->setTabVisible(ui->tabWidget->indexOf(ui->tabSendMessagePort2), (oTabWidget == ui->tabSendMessagePort2)); } void cMainWindow::clearOpenConnection() { ui->edtPortName->clear(); } void cMainWindow::clearSendMessagePort1() { ui->edtSendMessagePort1->clear(); } void cMainWindow::clearSendMessagePort2() { ui->edtSendMessagePort2->clear(); } void cMainWindow::on_actionOpenConnection_triggered() { if (m_connections.size() == 2) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("Le nombre maximal de connexions est atteint.")); return; } ui->stackedWidget->setCurrentWidget(ui->pageOpenConnection); } void cMainWindow::on_actionDisplayConnection_triggered() { ui->stackedWidget->setCurrentWidget(ui->pageDisplayConnection); } void cMainWindow::on_btnOpenConnection_clicked() { QString oPortName = ui->edtPortName->text(); if (oPortName.isEmpty()) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("Le nom du port est obligatoire.")); return; } if (isActive(oPortName)) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("Le port série est déjà ouvert.")); return; } QSerialPort *oSerialPort = new QSerialPort(this); connect(oSerialPort, &QSerialPort::readyRead, this, &cMainWindow::onReadyData); connect(oSerialPort, &QSerialPort::errorOccurred, this, &cMainWindow::onErrorOccurred); oSerialPort->setPortName(oPortName); oSerialPort->setBaudRate(QSerialPort::Baud9600); oSerialPort->setDataBits(QSerialPort::Data8); oSerialPort->setFlowControl(QSerialPort::NoFlowControl); oSerialPort->setParity(QSerialPort::NoParity); oSerialPort->setStopBits(QSerialPort::OneStop); oSerialPort->open(QIODevice::ReadWrite); if (!oSerialPort->isOpen()) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("La connexion au port série a échoué.")); return; } QMessageBox::information(this, tr("Messages d'informations"), tr("La connexion au port série a réussi.")); m_connections.push_back(oSerialPort); addConnection(oPortName); addPortToTab(oPortName); clearOpenConnection(); ui->stackedWidget->setCurrentWidget(ui->pageHome); } void cMainWindow::on_btnSendMessagePort1_clicked() { QString oMessage = ui->edtSendMessagePort1->toPlainText(); if (oMessage.isEmpty()) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("Le message est obligatoire.")); return; } QString oPortName; if (!loadPortToTab(ui->tabSendMessagePort1, oPortName)) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("Le nom du port est inconnu.")); return; } QSerialPort *oSerialPort; if (!loadConnection(oPortName, &oSerialPort)) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("La connexion port série est introuvable.")); return; } cMessageSend *oMessageSend = new cMessageSend(oMessage); ui->messageLayoutPort1->addWidget(oMessageSend); ui->scrollAreaPort1->widget()->adjustSize(); qApp->processEvents(); ui->scrollAreaPort1->verticalScrollBar()->setValue(ui->scrollAreaPort1->verticalScrollBar()->maximum()); oSerialPort->write(oMessage.toUtf8()); clearSendMessagePort1(); qDebug() << "L'envoi de message est termine." << "|portName=" << oSerialPort->portName() << "|message=" << oMessage.left(50); } void cMainWindow::on_btnSendMessagePort2_clicked() { QString oMessage = ui->edtSendMessagePort2->toPlainText(); if (oMessage.isEmpty()) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("Le message est obligatoire.")); return; } QString oPortName; if (!loadPortToTab(ui->tabSendMessagePort2, oPortName)) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("Le nom du port est inconnu.")); return; } QSerialPort *oSerialPort; if (!loadConnection(oPortName, &oSerialPort)) { QMessageBox::critical(this, tr("Messages d'erreurs"), tr("La connexion port série est introuvable.")); return; } cMessageSend *oMessageSend = new cMessageSend(oMessage); ui->messageLayoutPort2->addWidget(oMessageSend); ui->scrollAreaPort2->widget()->adjustSize(); qApp->processEvents(); ui->scrollAreaPort2->verticalScrollBar()->setValue(ui->scrollAreaPort2->verticalScrollBar()->maximum()); oSerialPort->write(oMessage.toUtf8()); clearSendMessagePort2(); qDebug() << "L'envoi de message est termine." << "|portName=" << oSerialPort->portName() << "|message=" << oMessage.left(50); } void cMainWindow::onReadyData() { QSerialPort *oSerialPort = qobject_cast<QSerialPort *>(sender()); QByteArray oMessage = oSerialPort->readAll(); QString oPortName = oSerialPort->portName(); QLayout *oMessageLayout; if (!loadPortToTab(oSerialPort->portName(), &oMessageLayout)) return; cMessageRecv *oMessageRecv = new cMessageRecv(oMessage); oMessageLayout->addWidget(oMessageRecv); qDebug() << "La reception de message est termine." << "|portName=" << oSerialPort->portName() << "|message=" << oMessage.left(50); } void cMainWindow::onErrorOccurred(QSerialPort::SerialPortError error) { if (error != QSerialPort::NoError) { QSerialPort *oSerialPort = qobject_cast<QSerialPort *>(sender()); qDebug() << "La connexion au port serie a echoue." << "|errorCode=" << error << "|portName=" << oSerialPort->portName(); } } void cMainWindow::onSendMessage(QAction *_action) { QString oPortName = _action->data().toString(); QSerialPort *oSerialPort; if (loadConnection(oPortName, &oSerialPort)) { ui->stackedWidget->setCurrentWidget(ui->pageSendMessage); showSendMessageTab(oPortName); qDebug() << "L'envoi de message a demarre." << "|portName=" << oSerialPort->portName(); } } ...
... #pragma once #include <QWidget> namespace Ui { class cPortAction; } class cPortAction : public QWidget { Q_OBJECT public: explicit cPortAction(const QString &_portName, QWidget *parent = 0); ~cPortAction(); private: void initActions(); private slots: void onSendMessage(); signals: void emitSendMessage(QAction *); private: Ui::cPortAction *ui; QString m_portName; }; ...
... #include "cPortAction.h" #include "ui_cPortAction.h" #include <QMenu> cPortAction::cPortAction(const QString &_portName, QWidget *parent) : QWidget(parent), ui(new Ui::cPortAction), m_portName(_portName) { ui->setupUi(this); ui->layActions->setAlignment(Qt::AlignCenter); initActions(); } cPortAction::~cPortAction() { delete ui; } void cPortAction::initActions() { QMenu *oMenu = new QMenu(this); QAction *oActions = new QAction("Envoyer un message"); oActions->setData(m_portName); oMenu->addAction(oActions); connect(oActions, &QAction::triggered, this, &cPortAction::onSendMessage); ui->btnActions->setMenu(oMenu); } void cPortAction::onSendMessage() { QAction *oActions = qobject_cast<QAction *>(sender()); emit emitSendMessage(oActions); } ...
... #pragma once #include <QWidget> namespace Ui { class cMessageSend; } class cMessageSend : public QWidget { Q_OBJECT public: explicit cMessageSend(const QString &_message, QWidget *parent = 0); ~cMessageSend(); private: Ui::cMessageSend *ui; QString m_message; }; ...
... #include "cMessageSend.h" #include "ui_cMessageSend.h" using namespace std::chrono_literals; cMessageSend::cMessageSend(const QString &_message, QWidget *parent) : QWidget(parent), ui(new Ui::cMessageSend), m_message(_message) { ui->setupUi(this); ui->layLogo->setAlignment(Qt::AlignTop); ui->lblMessage->setText(m_message); } cMessageSend::~cMessageSend() { delete ui; } ...
... #pragma once #include <QWidget> namespace Ui { class cMessageRecv; } class cMessageRecv : public QWidget { Q_OBJECT public: explicit cMessageRecv(const QString &_message, QWidget *parent = 0); ~cMessageRecv(); private: Ui::cMessageRecv *ui; QString m_message; }; ...
... #include "cMessageRecv.h" #include "ui_cMessageRecv.h" using namespace std::chrono_literals; cMessageRecv::cMessageRecv(const QString &_message, QWidget *parent) : QWidget(parent), ui(new Ui::cMessageRecv), m_message(_message) { ui->setupUi(this); ui->layLogo->setAlignment(Qt::AlignTop); ui->lblMessage->setText(m_message); } cMessageRecv::~cMessageRecv() { delete ui; } ...
... cmake_minimum_required(VERSION 3.10.0) project(rdvcpp VERSION 0.1.0 LANGUAGES C CXX) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_PREFIX_PATH "C:/Qt/6.5.2/msvc2019_64/lib/cmake") find_package(Qt6 REQUIRED COMPONENTS Widgets SerialPort ) qt_wrap_ui(UI_FILES cMainWindow.ui cPortAction.ui cMessageSend.ui cMessageRecv.ui ) add_executable(rdvcpp main.cpp cMainWindow.cpp cPortAction.cpp cMessageSend.cpp cMessageRecv.cpp resources.qrc ${UI_FILES} ) target_link_libraries (rdvcpp Qt6::Widgets Qt6::SerialPort ) ...
... <RCC> <qresource prefix="/img"> <file alias="logo.png">data/img/logo.png</file> </qresource> </RCC> ...
... rdvcpp.exe ...
... #include "cMainWindow.h" #include <QApplication> int main(int argc, char **argv) { QApplication app(argc, argv); cMainWindow *oMainWindow = new cMainWindow; oMainWindow->resize(400, 500); oMainWindow->show(); return app.exec(); } ...
... #pragma once #include <QMainWindow> class QLabel; class QSettings; namespace Ui { class cMainWindow; } class cMainWindow : public QMainWindow { Q_OBJECT public: struct sSettingsDTO { // General QString inputDevice; int bufferSize; int nanValue; bool isAfterGlow; int refreshRate; QString settingsPath; // Format QString displayFormat; QString binaryFormat; // Sacling double scalingA; double scalingB; bool isScalingEnabled; }; public: explicit cMainWindow(QWidget *parent = 0); ~cMainWindow(); private: void loadDefaultValue(sSettingsDTO &_settingsDTO); void readSettings(sSettingsDTO &_settingsDTO); void writeSettings(const sSettingsDTO &_settingsDTO); void saveSettings(QSettings &_settings, const sSettingsDTO &_settingsDTO); void loadSettings(QSettings &_settings, sSettingsDTO &_settingsDTO); protected: void closeEvent(QCloseEvent *event); private slots: void on_actionSaveSettings_triggered(); void on_actionLoadSettings_triggered(); void on_actionSettingsPage_triggered(); void on_btnSettingsOK_clicked(); private: Ui::cMainWindow *ui; QString m_settingsPath; }; ...
... #include "cMainWindow.h" #include "ui_cMainWindow.h" #include <QFileDialog> #include <QSettings> #include <QDir> #include <QFileInfo> #include <QMessageBox> #include <QCloseEvent> // Organization static const QString DEF_ORGANIZATION_NAME = "ReadyDEV"; static const QString DEF_APP_NAME = "ReadySCOPE"; // Settings : General static const QString DEF_INPUT_DEVICE = "InputDevice"; static const QString DEF_BUFFER_SIZE = "BufferSize"; static const QString DEF_NAN_VALUE = "NanValue"; static const QString DEF_AFTER_GLOW = "AfterGlow"; static const QString DEF_REFRESH_RATE = "RefreshRate"; static const QString DEF_SETTINGS_PATH = "SettingsPath"; // Settings : Format static const QString DEF_SETTINGS_FORMAT = "Format"; static const QString DEF_DISPLAY_FORMAT = "DisplayFormat"; static const QString DEF_BINARY_FORMAT = "BinaryFormat"; // Settings : Scaling static const QString DEF_SETTINGS_SCALING = "Scaling"; static const QString DEF_SCALING_A = "ScalingA"; static const QString DEF_SCALING_B = "ScalingB"; static const QString DEF_SCALING_ENABLED = "ScalingEnabled"; cMainWindow::cMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::cMainWindow) { ui->setupUi(this); ui->stackedWidget->setCurrentWidget(ui->pageHome); QSettings oSettings(DEF_ORGANIZATION_NAME, DEF_APP_NAME); sSettingsDTO oSettingsDTO; loadSettings(oSettings, oSettingsDTO); writeSettings(oSettingsDTO); } cMainWindow::~cMainWindow() { delete ui; } void cMainWindow::loadDefaultValue(sSettingsDTO &_settingsDTO) { // General _settingsDTO.inputDevice = "[input-device]"; _settingsDTO.bufferSize = 100000; _settingsDTO.nanValue = 0; _settingsDTO.isAfterGlow = false; _settingsDTO.refreshRate = 10; _settingsDTO.settingsPath = QDir::homePath(); // Format _settingsDTO.displayFormat = "[display-format]"; _settingsDTO.binaryFormat = "[binary-format]"; // Scaling _settingsDTO.scalingA = 1.0; _settingsDTO.scalingB = 0.0; _settingsDTO.isScalingEnabled = false; } void cMainWindow::readSettings(sSettingsDTO &_settingsDTO) { // General _settingsDTO.inputDevice = ui->edtInputDevice->text(); _settingsDTO.bufferSize = ui->edtBufferSize->value(); _settingsDTO.nanValue = ui->edtNanValue->value(); _settingsDTO.isAfterGlow = ui->radAfterGlowYes->isChecked(); _settingsDTO.refreshRate = ui->edtRefreshRate->value(); _settingsDTO.settingsPath = m_settingsPath; // Format _settingsDTO.displayFormat = ui->edtDisplayFormat->text(); _settingsDTO.binaryFormat = ui->edtBinaryFormat->text(); // Scaling _settingsDTO.scalingA = ui->edtScalingA->value(); _settingsDTO.scalingB = ui->edtScalingB->value(); _settingsDTO.isScalingEnabled = ui->chbScalingEnabled->isChecked(); } void cMainWindow::writeSettings(const sSettingsDTO &_settingsDTO) { // General ui->edtInputDevice->setText(_settingsDTO.inputDevice); ui->edtBufferSize->setValue(_settingsDTO.bufferSize); ui->edtNanValue->setValue(_settingsDTO.nanValue); ui->radAfterGlowYes->setChecked(_settingsDTO.isAfterGlow); ui->radAfterGlowNo->setChecked(!_settingsDTO.isAfterGlow); ui->edtRefreshRate->setValue(_settingsDTO.refreshRate); m_settingsPath = _settingsDTO.settingsPath; // Format ui->edtDisplayFormat->setText(_settingsDTO.displayFormat); ui->edtBinaryFormat->setText(_settingsDTO.binaryFormat); // Scaling ui->edtScalingA->setValue(_settingsDTO.scalingA); ui->edtScalingB->setValue(_settingsDTO.scalingB); ui->chbScalingEnabled->setChecked(_settingsDTO.isScalingEnabled); } void cMainWindow::saveSettings(QSettings &_settings, const sSettingsDTO &_settingsDTO) { // General _settings.setValue(DEF_INPUT_DEVICE, _settingsDTO.inputDevice); _settings.setValue(DEF_BUFFER_SIZE, _settingsDTO.bufferSize); _settings.setValue(DEF_NAN_VALUE, _settingsDTO.nanValue); _settings.setValue(DEF_AFTER_GLOW, _settingsDTO.isAfterGlow); _settings.setValue(DEF_REFRESH_RATE, _settingsDTO.refreshRate); _settings.setValue(DEF_SETTINGS_PATH, _settingsDTO.settingsPath); // Format _settings.beginGroup(DEF_SETTINGS_FORMAT); _settings.setValue(DEF_DISPLAY_FORMAT, _settingsDTO.displayFormat); _settings.setValue(DEF_BINARY_FORMAT, _settingsDTO.binaryFormat); _settings.endGroup(); // Scaling _settings.beginGroup(DEF_SETTINGS_SCALING); _settings.setValue(DEF_SCALING_A, _settingsDTO.scalingA); _settings.setValue(DEF_SCALING_B, _settingsDTO.scalingB); _settings.setValue(DEF_SCALING_ENABLED, _settingsDTO.isScalingEnabled); _settings.endGroup(); } void cMainWindow::loadSettings(QSettings &_settings, sSettingsDTO &_settingsDTO) { sSettingsDTO oSettingsDTO; loadDefaultValue(oSettingsDTO); // General _settingsDTO.inputDevice = _settings.value(DEF_INPUT_DEVICE, oSettingsDTO.inputDevice).toString(); _settingsDTO.bufferSize = _settings.value(DEF_BUFFER_SIZE, oSettingsDTO.bufferSize).toInt(); _settingsDTO.nanValue = _settings.value(DEF_NAN_VALUE, oSettingsDTO.nanValue).toInt(); _settingsDTO.isAfterGlow = _settings.value(DEF_AFTER_GLOW, oSettingsDTO.isAfterGlow).toBool(); _settingsDTO.refreshRate = _settings.value(DEF_REFRESH_RATE, oSettingsDTO.refreshRate).toInt(); _settingsDTO.settingsPath = _settings.value(DEF_SETTINGS_PATH, oSettingsDTO.settingsPath).toString(); // Format _settings.beginGroup(DEF_SETTINGS_FORMAT); _settingsDTO.displayFormat = _settings.value(DEF_DISPLAY_FORMAT, oSettingsDTO.displayFormat).toString(); _settingsDTO.binaryFormat = _settings.value(DEF_BINARY_FORMAT, oSettingsDTO.binaryFormat).toString(); _settings.endGroup(); // Scaling _settings.beginGroup(DEF_SETTINGS_SCALING); _settingsDTO.scalingA = _settings.value(DEF_SCALING_A, oSettingsDTO.scalingA).toDouble(); _settingsDTO.scalingB = _settings.value(DEF_SCALING_B, oSettingsDTO.scalingB).toDouble(); _settingsDTO.isScalingEnabled = _settings.value(DEF_SCALING_ENABLED, oSettingsDTO.isScalingEnabled).toBool(); _settings.endGroup(); } void cMainWindow::closeEvent(QCloseEvent *event) { sSettingsDTO oSettingsDTO; readSettings(oSettingsDTO); QSettings oSettings(DEF_ORGANIZATION_NAME, DEF_APP_NAME); saveSettings(oSettings, oSettingsDTO); } void cMainWindow::on_actionSaveSettings_triggered() { QString oFilename = QFileDialog::getSaveFileName(this, tr("Sauvegarder les configurations"), m_settingsPath, tr("Settings (*.ini)")); if (oFilename.isEmpty()) { qDebug() << "L'enregistrement des configurations a ete annule."; return; } m_settingsPath = QFileInfo(oFilename).absolutePath(); sSettingsDTO oSettingsDTO; readSettings(oSettingsDTO); QSettings oSettings(oFilename, QSettings::IniFormat); saveSettings(oSettings, oSettingsDTO); qDebug() << "L'enregistrement des configurations s'est bien deroule." << "|filename=" << oFilename; } void cMainWindow::on_actionLoadSettings_triggered() { QString oFilename = QFileDialog::getOpenFileName(this, tr("Charger les configurations"), m_settingsPath, tr("Settings (*.ini)")); if (oFilename.isEmpty()) { qDebug() << "Le chargement des configurations a ete annule."; return; } m_settingsPath = QFileInfo(oFilename).absolutePath(); sSettingsDTO oSettingsDTO; QSettings oSettings(oFilename, QSettings::IniFormat); loadSettings(oSettings, oSettingsDTO); writeSettings(oSettingsDTO); qDebug() << "Le chargement des configurations s'est bien deroule." << "|filename=" << oFilename; } void cMainWindow::on_actionSettingsPage_triggered() { ui->stackedWidget->setCurrentWidget(ui->pageSettings); } void cMainWindow::on_btnSettingsOK_clicked() { ui->stackedWidget->setCurrentWidget(ui->pageHome); } ...
... cmake_minimum_required(VERSION 3.10.0) project(rdvcpp VERSION 0.1.0 LANGUAGES C CXX) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_PREFIX_PATH "C:/Qt/6.5.2/msvc2019_64/lib/cmake") find_package(Qt6 REQUIRED COMPONENTS Widgets ) qt_wrap_ui(UI_FILES cMainWindow.ui ) add_executable(rdvcpp main.cpp cMainWindow.cpp resources.qrc ${UI_FILES} ) target_link_libraries (rdvcpp Qt6::Widgets ) ...
... <RCC> <qresource prefix="/img"> <file alias="logo.png">data/img/logo.png</file> </qresource> </RCC> ...
... rdvcpp.exe ...