diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/serialbus/can/bitratebox.h | 2 | ||||
-rw-r--r-- | examples/serialbus/can/can.pro | 6 | ||||
-rw-r--r-- | examples/serialbus/can/connectdialog.cpp | 14 | ||||
-rw-r--r-- | examples/serialbus/can/connectdialog.h | 4 | ||||
-rw-r--r-- | examples/serialbus/can/connectdialog.ui | 6 | ||||
-rw-r--r-- | examples/serialbus/can/mainwindow.cpp | 107 | ||||
-rw-r--r-- | examples/serialbus/can/mainwindow.h | 11 | ||||
-rw-r--r-- | examples/serialbus/can/mainwindow.ui | 125 | ||||
-rw-r--r-- | examples/serialbus/can/sendframebox.cpp | 201 | ||||
-rw-r--r-- | examples/serialbus/can/sendframebox.h | 112 | ||||
-rw-r--r-- | examples/serialbus/can/sendframebox.ui | 211 | ||||
-rw-r--r-- | examples/serialbus/modbus/adueditor/adueditor.pro | 1 | ||||
-rw-r--r-- | examples/serialbus/modbus/adueditor/mainwindow.cpp | 2 | ||||
-rw-r--r-- | examples/serialbus/modbus/master/master.pro | 1 | ||||
-rw-r--r-- | examples/serialbus/modbus/slave/slave.pro | 1 |
15 files changed, 600 insertions, 204 deletions
diff --git a/examples/serialbus/can/bitratebox.h b/examples/serialbus/can/bitratebox.h index d15ea9b..9156104 100644 --- a/examples/serialbus/can/bitratebox.h +++ b/examples/serialbus/can/bitratebox.h @@ -60,7 +60,7 @@ QT_END_NAMESPACE class BitRateBox : public QComboBox { public: - BitRateBox(QWidget *parent = nullptr); + explicit BitRateBox(QWidget *parent = nullptr); ~BitRateBox(); int bitRate() const; diff --git a/examples/serialbus/can/can.pro b/examples/serialbus/can/can.pro index c667dbb..81e29ee 100644 --- a/examples/serialbus/can/can.pro +++ b/examples/serialbus/can/can.pro @@ -1,4 +1,5 @@ QT += serialbus widgets +requires(qtConfig(combobox)) TARGET = can TEMPLATE = app @@ -8,14 +9,17 @@ SOURCES += \ connectdialog.cpp \ main.cpp \ mainwindow.cpp \ + sendframebox.cpp HEADERS += \ bitratebox.h \ connectdialog.h \ mainwindow.h \ + sendframebox.h FORMS += mainwindow.ui \ - connectdialog.ui + connectdialog.ui \ + sendframebox.ui RESOURCES += can.qrc diff --git a/examples/serialbus/can/connectdialog.cpp b/examples/serialbus/can/connectdialog.cpp index ae6e7f0..5a12592 100644 --- a/examples/serialbus/can/connectdialog.cpp +++ b/examples/serialbus/can/connectdialog.cpp @@ -78,14 +78,14 @@ ConnectDialog::ConnectDialog(QWidget *parent) : connect(m_ui->cancelButton, &QPushButton::clicked, this, &ConnectDialog::cancel); connect(m_ui->useConfigurationBox, &QCheckBox::clicked, m_ui->configurationBox, &QGroupBox::setEnabled); - connect(m_ui->backendListBox, &QComboBox::currentTextChanged, - this, &ConnectDialog::backendChanged); + connect(m_ui->pluginListBox, &QComboBox::currentTextChanged, + this, &ConnectDialog::pluginChanged); connect(m_ui->interfaceListBox, &QComboBox::currentTextChanged, this, &ConnectDialog::interfaceChanged); m_ui->rawFilterEdit->hide(); m_ui->rawFilterLabel->hide(); - m_ui->backendListBox->addItems(QCanBus::instance()->plugins()); + m_ui->pluginListBox->addItems(QCanBus::instance()->plugins()); updateSettings(); } @@ -100,10 +100,10 @@ ConnectDialog::Settings ConnectDialog::settings() const return m_currentSettings; } -void ConnectDialog::backendChanged(const QString &backend) +void ConnectDialog::pluginChanged(const QString &plugin) { m_ui->interfaceListBox->clear(); - m_interfaces = QCanBus::instance()->availableDevices(backend); + m_interfaces = QCanBus::instance()->availableDevices(plugin); for (const QCanBusDeviceInfo &info : qAsConst(m_interfaces)) m_ui->interfaceListBox->addItem(info.name()); } @@ -156,7 +156,7 @@ QString ConnectDialog::configurationValue(QCanBusDevice::ConfigurationKey key) void ConnectDialog::revertSettings() { - m_ui->backendListBox->setCurrentText(m_currentSettings.backendName); + m_ui->pluginListBox->setCurrentText(m_currentSettings.pluginName); m_ui->interfaceListBox->setCurrentText(m_currentSettings.deviceInterfaceName); m_ui->useConfigurationBox->setChecked(m_currentSettings.useConfigurationEnabled); @@ -181,7 +181,7 @@ void ConnectDialog::revertSettings() void ConnectDialog::updateSettings() { - m_currentSettings.backendName = m_ui->backendListBox->currentText(); + m_currentSettings.pluginName = m_ui->pluginListBox->currentText(); m_currentSettings.deviceInterfaceName = m_ui->interfaceListBox->currentText(); m_currentSettings.useConfigurationEnabled = m_ui->useConfigurationBox->isChecked(); diff --git a/examples/serialbus/can/connectdialog.h b/examples/serialbus/can/connectdialog.h index f2ad9bf..d7a0a55 100644 --- a/examples/serialbus/can/connectdialog.h +++ b/examples/serialbus/can/connectdialog.h @@ -72,7 +72,7 @@ public: typedef QPair<QCanBusDevice::ConfigurationKey, QVariant> ConfigurationItem; struct Settings { - QString backendName; + QString pluginName; QString deviceInterfaceName; QList<ConfigurationItem> configurations; bool useConfigurationEnabled = false; @@ -84,7 +84,7 @@ public: Settings settings() const; private slots: - void backendChanged(const QString &backend); + void pluginChanged(const QString &plugin); void interfaceChanged(const QString &interface); void ok(); void cancel(); diff --git a/examples/serialbus/can/connectdialog.ui b/examples/serialbus/can/connectdialog.ui index aad6bef..def6e59 100644 --- a/examples/serialbus/can/connectdialog.ui +++ b/examples/serialbus/can/connectdialog.ui @@ -55,13 +55,13 @@ </layout> </item> <item row="0" column="0"> - <widget class="QGroupBox" name="selectBackendBox"> + <widget class="QGroupBox" name="selectPluginBox"> <property name="title"> - <string>Select CAN backend</string> + <string>Select CAN plugin</string> </property> <layout class="QGridLayout" name="gridLayout"> <item row="0" column="0"> - <widget class="QComboBox" name="backendListBox"/> + <widget class="QComboBox" name="pluginListBox"/> </item> </layout> </widget> diff --git a/examples/serialbus/can/mainwindow.cpp b/examples/serialbus/can/mainwindow.cpp index 1d95f22..fd5861f 100644 --- a/examples/serialbus/can/mainwindow.cpp +++ b/examples/serialbus/can/mainwindow.cpp @@ -56,7 +56,6 @@ #include <QCanBusFrame> #include <QCloseEvent> #include <QDesktopServices> -#include <QtDebug> #include <QTimer> MainWindow::MainWindow(QWidget *parent) : @@ -68,14 +67,13 @@ MainWindow::MainWindow(QWidget *parent) : m_connectDialog = new ConnectDialog; m_status = new QLabel; - m_ui->statusBar->addWidget(m_status); + m_ui->statusBar->addPermanentWidget(m_status); - m_ui->sendMessagesBox->setEnabled(false); + m_written = new QLabel; + m_ui->statusBar->addWidget(m_written); initActionsConnections(); QTimer::singleShot(50, m_connectDialog, &ConnectDialog::show); - - connect(m_ui->sendButton, &QPushButton::clicked, this, &MainWindow::sendMessage); } MainWindow::~MainWindow() @@ -86,17 +84,12 @@ MainWindow::~MainWindow() delete m_ui; } -void MainWindow::showStatusMessage(const QString &message) -{ - m_status->setText(message); -} - void MainWindow::initActionsConnections() { - m_ui->actionConnect->setEnabled(true); m_ui->actionDisconnect->setEnabled(false); - m_ui->actionQuit->setEnabled(true); + m_ui->sendFrameBox->setEnabled(false); + connect(m_ui->sendFrameBox, &SendFrameBox::sendFrame, this, &MainWindow::sendFrame); connect(m_ui->actionConnect, &QAction::triggered, m_connectDialog, &ConnectDialog::show); connect(m_connectDialog, &QDialog::accepted, this, &MainWindow::connectDevice); connect(m_ui->actionDisconnect, &QAction::triggered, this, &MainWindow::disconnectDevice); @@ -108,7 +101,7 @@ void MainWindow::initActionsConnections() }); } -void MainWindow::receiveError(QCanBusDevice::CanBusError error) const +void MainWindow::processErrors(QCanBusDevice::CanBusError error) const { switch (error) { case QCanBusDevice::ReadError: @@ -116,7 +109,8 @@ void MainWindow::receiveError(QCanBusDevice::CanBusError error) const case QCanBusDevice::ConnectionError: case QCanBusDevice::ConfigurationError: case QCanBusDevice::UnknownError: - qWarning() << m_canDevice->errorString(); + m_status->setText(m_canDevice->errorString()); + break; default: break; } @@ -127,20 +121,19 @@ void MainWindow::connectDevice() const ConnectDialog::Settings p = m_connectDialog->settings(); QString errorString; - m_canDevice = QCanBus::instance()->createDevice(p.backendName, p.deviceInterfaceName, + m_canDevice = QCanBus::instance()->createDevice(p.pluginName, p.deviceInterfaceName, &errorString); if (!m_canDevice) { - showStatusMessage(tr("Error creating device '%1', reason: '%2'") - .arg(p.backendName).arg(errorString)); + m_status->setText(tr("Error creating device '%1', reason: '%2'") + .arg(p.pluginName).arg(errorString)); return; } - connect(m_canDevice, &QCanBusDevice::errorOccurred, - this, &MainWindow::receiveError); - connect(m_canDevice, &QCanBusDevice::framesReceived, - this, &MainWindow::checkMessages); - connect(m_canDevice, &QCanBusDevice::framesWritten, - this, &MainWindow::framesWritten); + m_numberFramesWritten = 0; + + connect(m_canDevice, &QCanBusDevice::errorOccurred, this, &MainWindow::processErrors); + connect(m_canDevice, &QCanBusDevice::framesReceived, this, &MainWindow::processReceivedFrames); + connect(m_canDevice, &QCanBusDevice::framesWritten, this, &MainWindow::processFramesWritten); if (p.useConfigurationEnabled) { for (const ConnectDialog::ConfigurationItem &item : p.configurations) @@ -148,7 +141,7 @@ void MainWindow::connectDevice() } if (!m_canDevice->connectDevice()) { - showStatusMessage(tr("Connection error: %1").arg(m_canDevice->errorString())); + m_status->setText(tr("Connection error: %1").arg(m_canDevice->errorString())); delete m_canDevice; m_canDevice = nullptr; @@ -156,16 +149,16 @@ void MainWindow::connectDevice() m_ui->actionConnect->setEnabled(false); m_ui->actionDisconnect->setEnabled(true); - m_ui->sendMessagesBox->setEnabled(true); + m_ui->sendFrameBox->setEnabled(true); QVariant bitRate = m_canDevice->configurationParameter(QCanBusDevice::BitRateKey); if (bitRate.isValid()) { - showStatusMessage(tr("Backend: %1, connected to %2 at %3 kBit/s") - .arg(p.backendName).arg(p.deviceInterfaceName) + m_status->setText(tr("Plugin: %1, connected to %2 at %3 kBit/s") + .arg(p.pluginName).arg(p.deviceInterfaceName) .arg(bitRate.toInt() / 1000)); } else { - showStatusMessage(tr("Backend: %1, connected to %2") - .arg(p.backendName).arg(p.deviceInterfaceName)); + m_status->setText(tr("Plugin: %1, connected to %2") + .arg(p.pluginName).arg(p.deviceInterfaceName)); } } } @@ -182,14 +175,15 @@ void MainWindow::disconnectDevice() m_ui->actionConnect->setEnabled(true); m_ui->actionDisconnect->setEnabled(false); - m_ui->sendMessagesBox->setEnabled(false); + m_ui->sendFrameBox->setEnabled(false); - showStatusMessage(tr("Disconnected")); + m_status->setText(tr("Disconnected")); } -void MainWindow::framesWritten(qint64 count) +void MainWindow::processFramesWritten(qint64 count) { - qDebug() << "Number of frames written:" << count; + m_numberFramesWritten += count; + m_written->setText(tr("%1 frames written").arg(m_numberFramesWritten)); } void MainWindow::closeEvent(QCloseEvent *event) @@ -200,16 +194,19 @@ void MainWindow::closeEvent(QCloseEvent *event) static QString frameFlags(const QCanBusFrame &frame) { - if (frame.hasBitrateSwitch() && frame.hasErrorStateIndicator()) - return QStringLiteral(" B E "); + QString result = QLatin1String(" --- "); + if (frame.hasBitrateSwitch()) - return QStringLiteral(" B - "); + result[1] = QLatin1Char('B'); if (frame.hasErrorStateIndicator()) - return QStringLiteral(" - E "); - return QStringLiteral(" - - "); + result[2] = QLatin1Char('E'); + if (frame.hasLocalEcho()) + result[3] = QLatin1Char('L'); + + return result; } -void MainWindow::checkMessages() +void MainWindow::processReceivedFrames() { if (!m_canDevice) return; @@ -233,40 +230,10 @@ void MainWindow::checkMessages() } } -static QByteArray dataFromHex(const QString &hex) -{ - QByteArray line = hex.toLatin1(); - line.replace(' ', QByteArray()); - return QByteArray::fromHex(line); -} - -void MainWindow::sendMessage() const +void MainWindow::sendFrame(const QCanBusFrame &frame) const { if (!m_canDevice) return; - QByteArray writings = dataFromHex(m_ui->lineEdit->displayText()); - - QCanBusFrame frame; - const int maxPayload = m_ui->fdBox->checkState() ? 64 : 8; - writings.truncate(maxPayload); - frame.setPayload(writings); - - qint32 id = m_ui->idEdit->displayText().toInt(nullptr, 16); - if (!m_ui->effBox->checkState() && id > 2047) //11 bits - id = 2047; - - frame.setFrameId(id); - frame.setExtendedFrameFormat(m_ui->effBox->checkState()); - frame.setFlexibleDataRateFormat(m_ui->fdBox->checkState()); - frame.setBitrateSwitch(m_ui->bitrateSwitchBox->checkState()); - - if (m_ui->remoteFrame->isChecked()) - frame.setFrameType(QCanBusFrame::RemoteRequestFrame); - else if (m_ui->errorFrame->isChecked()) - frame.setFrameType(QCanBusFrame::ErrorFrame); - else - frame.setFrameType(QCanBusFrame::DataFrame); - m_canDevice->writeFrame(frame); } diff --git a/examples/serialbus/can/mainwindow.h b/examples/serialbus/can/mainwindow.h index 273045f..40b2e4a 100644 --- a/examples/serialbus/can/mainwindow.h +++ b/examples/serialbus/can/mainwindow.h @@ -77,22 +77,23 @@ public: ~MainWindow(); private slots: - void checkMessages(); - void sendMessage() const; - void receiveError(QCanBusDevice::CanBusError) const; + void processReceivedFrames(); + void sendFrame(const QCanBusFrame &frame) const; + void processErrors(QCanBusDevice::CanBusError) const; void connectDevice(); void disconnectDevice(); - void framesWritten(qint64); + void processFramesWritten(qint64); protected: void closeEvent(QCloseEvent *event) override; private: - void showStatusMessage(const QString &message); void initActionsConnections(); + qint64 m_numberFramesWritten = 0; Ui::MainWindow *m_ui = nullptr; QLabel *m_status = nullptr; + QLabel *m_written = nullptr; ConnectDialog *m_connectDialog = nullptr; QCanBusDevice *m_canDevice = nullptr; }; diff --git a/examples/serialbus/can/mainwindow.ui b/examples/serialbus/can/mainwindow.ui index 04f8c93..1d5a657 100644 --- a/examples/serialbus/can/mainwindow.ui +++ b/examples/serialbus/can/mainwindow.ui @@ -14,123 +14,12 @@ <string>CAN Example</string> </property> <widget class="QWidget" name="centralWidget"> - <layout class="QVBoxLayout" name="verticalLayout_3"> + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QGroupBox" name="sendMessagesBox"> + <widget class="SendFrameBox" name="sendFrameBox"> <property name="title"> - <string>Send CAN message</string> + <string>Send CAN frame</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>&ID (hex)</string> - </property> - <property name="buddy"> - <cstring>idEdit</cstring> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLineEdit" name="idEdit"> - <property name="placeholderText"> - <string>123</string> - </property> - </widget> - </item> - <item row="0" column="2" rowspan="4"> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Frame Type</string> - </property> - <property name="checkable"> - <bool>false</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QRadioButton" name="dataFrame"> - <property name="text"> - <string>D&ata</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="remoteFrame"> - <property name="text"> - <string>Re&mote Request</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="errorFrame"> - <property name="text"> - <string>&Error</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="0" column="3"> - <widget class="QCheckBox" name="fdBox"> - <property name="text"> - <string>&Flexible Data-Rate -(64 byte payload)</string> - </property> - </widget> - </item> - <item row="2" column="3"> - <widget class="QCheckBox" name="effBox"> - <property name="toolTip"> - <string>Allow extended frames with 29 bit identifier. -Otherwise, the standard format with 11 bit idenfier is used.</string> - </property> - <property name="text"> - <string>E&xtended Frame -(29 bit identifier)</string> - </property> - </widget> - </item> - <item row="3" column="3"> - <widget class="QPushButton" name="sendButton"> - <property name="text"> - <string>&Send</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="lineEdit"> - <property name="placeholderText"> - <string>12 34 AB CE</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>&Data (hex)</string> - </property> - <property name="buddy"> - <cstring>lineEdit</cstring> - </property> - </widget> - </item> - <item row="1" column="3"> - <widget class="QCheckBox" name="bitrateSwitchBox"> - <property name="text"> - <string>&Bitrate Switch -(Higher data rate)</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> </widget> </item> <item> @@ -276,6 +165,14 @@ Otherwise, the standard format with 11 bit idenfier is used.</string> </action> </widget> <layoutdefault spacing="6" margin="11"/> + <customwidgets> + <customwidget> + <class>SendFrameBox</class> + <extends>QGroupBox</extends> + <header location="global">sendframebox.h</header> + <container>1</container> + </customwidget> + </customwidgets> <resources> <include location="can.qrc"/> </resources> diff --git a/examples/serialbus/can/sendframebox.cpp b/examples/serialbus/can/sendframebox.cpp new file mode 100644 index 0000000..117ff10 --- /dev/null +++ b/examples/serialbus/can/sendframebox.cpp @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the QtSerialBus module. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "sendframebox.h" +#include "ui_sendframebox.h" + +enum { + MaxStandardId = 0x7FF, + MaxExtendedId = 0x10000000 +}; + +enum { + MaxPayload = 8, + MaxPayloadFd = 64 +}; + +HexIntegerValidator::HexIntegerValidator(QObject *parent) : + QValidator(parent), + m_maximum(MaxStandardId) +{ +} + +QValidator::State HexIntegerValidator::validate(QString &input, int &) const +{ + bool ok; + uint value = input.toUInt(&ok, 16); + + if (!value) + return Intermediate; + + if (!ok || value > m_maximum) + return Invalid; + + return Acceptable; +} + +void HexIntegerValidator::setMaximum(uint maximum) +{ + m_maximum = maximum; +} + +HexStringValidator::HexStringValidator(QObject *parent) : + QValidator(parent), + m_maxLength(MaxPayload) +{ +} + +QValidator::State HexStringValidator::validate(QString &input, int &pos) const +{ + const int maxSize = 2 * m_maxLength; + const QChar space = QLatin1Char(' '); + QString data = input; + data.remove(space); + + if (data.isEmpty()) + return Intermediate; + + // limit maximum size and forbid trailing spaces + if ((data.size() > maxSize) || (data.size() == maxSize && input.endsWith(space))) + return Invalid; + + // check if all input is valid + const QRegularExpression re(QStringLiteral("^[[:xdigit:]]*$")); + if (!re.match(data).hasMatch()) + return Invalid; + + // insert a space after every two hex nibbles + const QRegularExpression insertSpace(QStringLiteral("(?:[[:xdigit:]]{2} )*[[:xdigit:]]{3}")); + if (insertSpace.match(input).hasMatch()) { + input.insert(input.size() - 1, space); + pos = input.size(); + } + + return Acceptable; +} + +void HexStringValidator::setMaxLength(int maxLength) +{ + m_maxLength = maxLength; +} + +SendFrameBox::SendFrameBox(QWidget *parent) : + QGroupBox(parent), + m_ui(new Ui::SendFrameBox) +{ + m_ui->setupUi(this); + + m_hexIntegerValidator = new HexIntegerValidator(this); + m_ui->frameIdEdit->setValidator(m_hexIntegerValidator); + m_hexStringValidator = new HexStringValidator(this); + m_ui->payloadEdit->setValidator(m_hexStringValidator); + + connect(m_ui->dataFrame, &QRadioButton::toggled, [this](bool set) { + if (set) + m_ui->flexibleDataRateBox->setEnabled(true); + }); + + connect(m_ui->remoteFrame, &QRadioButton::toggled, [this](bool set) { + if (set) { + m_ui->flexibleDataRateBox->setEnabled(false); + m_ui->flexibleDataRateBox->setChecked(false); + } + }); + + connect(m_ui->errorFrame, &QRadioButton::toggled, [this](bool set) { + if (set) { + m_ui->flexibleDataRateBox->setEnabled(false); + m_ui->flexibleDataRateBox->setChecked(false); + } + }); + + connect(m_ui->extendedFormatBox, &QCheckBox::toggled, [this](bool set) { + m_hexIntegerValidator->setMaximum(set ? MaxExtendedId : MaxStandardId); + }); + + connect(m_ui->flexibleDataRateBox, &QCheckBox::toggled, [this](bool set) { + m_hexStringValidator->setMaxLength(set ? MaxPayloadFd : MaxPayload); + m_ui->bitrateSwitchBox->setEnabled(set); + if (!set) + m_ui->bitrateSwitchBox->setChecked(false); + }); + + auto frameIdTextChanged = [this]() { + const bool hasFrameId = !m_ui->frameIdEdit->text().isEmpty(); + m_ui->sendButton->setEnabled(hasFrameId); + m_ui->sendButton->setToolTip(hasFrameId + ? QString() : tr("Cannot send because no Frame ID was given.")); + }; + connect(m_ui->frameIdEdit, &QLineEdit::textChanged, frameIdTextChanged); + frameIdTextChanged(); + + connect(m_ui->sendButton, &QPushButton::clicked, [this]() { + const uint frameId = m_ui->frameIdEdit->text().toUInt(nullptr, 16); + QString data = m_ui->payloadEdit->text(); + const QByteArray payload = QByteArray::fromHex(data.remove(QLatin1Char(' ')).toLatin1()); + + QCanBusFrame frame = QCanBusFrame(frameId, payload); + frame.setExtendedFrameFormat(m_ui->extendedFormatBox->isChecked()); + frame.setFlexibleDataRateFormat(m_ui->flexibleDataRateBox->isChecked()); + frame.setBitrateSwitch(m_ui->bitrateSwitchBox->isChecked()); + + if (m_ui->errorFrame->isChecked()) + frame.setFrameType(QCanBusFrame::ErrorFrame); + else if (m_ui->remoteFrame->isChecked()) + frame.setFrameType(QCanBusFrame::RemoteRequestFrame); + + emit sendFrame(frame); + }); +} + +SendFrameBox::~SendFrameBox() +{ + delete m_ui; +} diff --git a/examples/serialbus/can/sendframebox.h b/examples/serialbus/can/sendframebox.h new file mode 100644 index 0000000..e8459c5 --- /dev/null +++ b/examples/serialbus/can/sendframebox.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the QtSerialBus module. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SENDFRAMEBOX_H +#define SENDFRAMEBOX_H + +#include <QCanBusFrame> +#include <QGroupBox> +#include <QRegularExpression> +#include <QValidator> + +QT_BEGIN_NAMESPACE +namespace Ui { +class SendFrameBox; +} +QT_END_NAMESPACE + +class HexIntegerValidator : public QValidator +{ + Q_OBJECT +public: + explicit HexIntegerValidator(QObject *parent = nullptr); + + QValidator::State validate(QString &input, int &) const; + + void setMaximum(uint maximum); + +private: + uint m_maximum = 0; +}; + +class HexStringValidator : public QValidator +{ + Q_OBJECT + +public: + explicit HexStringValidator(QObject *parent = nullptr); + + QValidator::State validate(QString &input, int &pos) const; + + void setMaxLength(int maxLength); + +private: + int m_maxLength = 0; +}; + +class SendFrameBox : public QGroupBox +{ + Q_OBJECT + +public: + explicit SendFrameBox(QWidget *parent = nullptr); + ~SendFrameBox(); + +signals: + void sendFrame(const QCanBusFrame &frame); + +private: + Ui::SendFrameBox *m_ui = nullptr; + + HexIntegerValidator *m_hexIntegerValidator = nullptr; + HexStringValidator *m_hexStringValidator = nullptr; +}; + +#endif // SENDFRAMEBOX_H diff --git a/examples/serialbus/can/sendframebox.ui b/examples/serialbus/can/sendframebox.ui new file mode 100644 index 0000000..0abeff5 --- /dev/null +++ b/examples/serialbus/can/sendframebox.ui @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SendFrameBox</class> + <widget class="QGroupBox" name="SendFrameBox"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>485</width> + <height>206</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <property name="title"> + <string/> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QGroupBox" name="frameTypeBox"> + <property name="title"> + <string>Frame Type</string> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="topMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QRadioButton" name="dataFrame"> + <property name="toolTip"> + <string>Sends a CAN data frame.</string> + </property> + <property name="text"> + <string>D&ata Frame</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="remoteFrame"> + <property name="toolTip"> + <string>Sends a CAN remote request frame.</string> + </property> + <property name="text"> + <string>Re&mote Request Frame</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="errorFrame"> + <property name="toolTip"> + <string>Sends an error frame.</string> + </property> + <property name="text"> + <string>&Error Frame</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="frameOptionsBox"> + <property name="title"> + <string>Frame Options</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QCheckBox" name="extendedFormatBox"> + <property name="toolTip"> + <string>Allows extended frames with 29 bit identifier.</string> + </property> + <property name="text"> + <string>E&xtended Format</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="flexibleDataRateBox"> + <property name="toolTip"> + <string>Allows up to 64 byte payload data.</string> + </property> + <property name="text"> + <string>&Flexible Data-Rate</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="bitrateSwitchBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Sends payload at higher data rate.</string> + </property> + <property name="text"> + <string>&Bitrate Switch</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="frameIdLabel"> + <property name="text"> + <string>Frame &ID (hex)</string> + </property> + <property name="buddy"> + <cstring>frameIdEdit</cstring> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="frameIdEdit"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="placeholderText"> + <string>123</string> + </property> + <property name="clearButtonEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="payloadLabel"> + <property name="text"> + <string>&Payload (hex)</string> + </property> + <property name="buddy"> + <cstring>payloadEdit</cstring> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="payloadEdit"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>2</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="placeholderText"> + <string>12 34 AB CE</string> + </property> + <property name="clearButtonEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="sendButton"> + <property name="text"> + <string>&Send</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/examples/serialbus/modbus/adueditor/adueditor.pro b/examples/serialbus/modbus/adueditor/adueditor.pro index a6a71f6..bba3c0d 100644 --- a/examples/serialbus/modbus/adueditor/adueditor.pro +++ b/examples/serialbus/modbus/adueditor/adueditor.pro @@ -4,6 +4,7 @@ INCLUDEPATH += . TARGET = adueditor QT += serialbus serialport widgets QT += serialbus-private core-private +requires(qtConfig(combobox)) FORMS += interface.ui SOURCES += main.cpp mainwindow.cpp modbustcpclient.cpp diff --git a/examples/serialbus/modbus/adueditor/mainwindow.cpp b/examples/serialbus/modbus/adueditor/mainwindow.cpp index beabfdf..862be6a 100644 --- a/examples/serialbus/modbus/adueditor/mainwindow.cpp +++ b/examples/serialbus/modbus/adueditor/mainwindow.cpp @@ -198,7 +198,7 @@ void MainWindow::on_connectButton_clicked() emit disconnectButton->clicked(); }, Qt::QueuedConnection); - connect(m_device, &QModbusDevice::stateChanged, [this](QModbusDevice::State state) { + connect(m_device, &QModbusDevice::stateChanged, [](QModbusDevice::State state) { switch (state) { case QModbusDevice::UnconnectedState: qDebug().noquote() << QStringLiteral("State: Entered unconnected state."); diff --git a/examples/serialbus/modbus/master/master.pro b/examples/serialbus/modbus/master/master.pro index 536b559..682ce82 100644 --- a/examples/serialbus/modbus/master/master.pro +++ b/examples/serialbus/modbus/master/master.pro @@ -1,4 +1,5 @@ QT += serialbus serialport widgets +requires(qtConfig(combobox)) TARGET = modbusmaster TEMPLATE = app diff --git a/examples/serialbus/modbus/slave/slave.pro b/examples/serialbus/modbus/slave/slave.pro index edf3e46..b803c5d 100644 --- a/examples/serialbus/modbus/slave/slave.pro +++ b/examples/serialbus/modbus/slave/slave.pro @@ -1,4 +1,5 @@ QT += serialbus serialport widgets +requires(qtConfig(combobox)) TARGET = modbusslave TEMPLATE = app |