client move ui helpers to folder

This commit is contained in:
2026-02-14 14:31:08 +01:00
parent 82b4dbb161
commit 8c585c712b
11 changed files with 0 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
#include "better_radiobutton.hpp"
Better_Radiobutton::Better_Radiobutton(QWidget *parent) : QWidget{parent}, m_radiobuttons{}
{
}
Better_Radiobutton::Better_Radiobutton(std::vector<QString> names, QWidget *parent)
: QWidget{parent}, m_v_layout{new QVBoxLayout(this)}, m_radiobuttons{}, m_checked{""}
{
for (const auto &name : names)
{
add_radiobutton(name);
}
}
void Better_Radiobutton::add_radiobutton(QString name)
{
auto radiobutton = new QRadioButton(name, this);
m_radiobuttons.push_back(radiobutton);
m_v_layout->addWidget(radiobutton);
connect(radiobutton, &QRadioButton::toggled, this, [this, name, radiobutton] {
emit toggled(name);
if (radiobutton->isChecked())
{
m_checked = name;
emit checked(name);
}
});
}
QString Better_Radiobutton::isChecked() const
{
return m_checked;
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef BETTER_RADIOBUTTON_H
#define BETTER_RADIOBUTTON_H
#include <QRadioButton>
#include <QVBoxLayout>
class Better_Radiobutton : public QWidget
{
Q_OBJECT
public:
explicit Better_Radiobutton(QWidget *parent = nullptr);
explicit Better_Radiobutton(std::vector<QString> names, QWidget *partent = nullptr);
void add_radiobutton(QString name);
QString isChecked() const;
signals:
void toggled(QString name);
void checked(QString name);
private:
QVBoxLayout *m_v_layout;
std::vector<QRadioButton *> m_radiobuttons;
QString m_checked;
};
#endif // BETTER_RADIOBUTTON_H
+77
View File
@@ -0,0 +1,77 @@
#include "can_transceive.hpp"
#include "ui_can_transceive.h"
Can_Transceive::Can_Transceive(QWidget *parent) : QWidget(parent), ui(new Ui::Can_Transceive)
{
ui->setupUi(this);
can_send_hexspinboxes = {
ui->s_can_send_data0, ui->s_can_send_data1, ui->s_can_send_data2, ui->s_can_send_data3,
ui->s_can_send_data4, ui->s_can_send_data5, ui->s_can_send_data6, ui->s_can_send_data7,
};
enable_can_send_data();
connect(ui->c_can_send_dlc, &QComboBox::currentIndexChanged, this, [=, this] { enable_can_send_data(); });
connect(ui->b_can_send_send, &QPushButton::clicked, this, [=, this] {
emit send_can_message(
ui->s_can_send_sid->value(), ui->c_can_send_dlc->currentIndex(),
std::array<uint8_t, 8>(
{(uint8_t)(can_send_hexspinboxes[0]->value()), (uint8_t)(can_send_hexspinboxes[1]->value()),
(uint8_t)(can_send_hexspinboxes[2]->value()), (uint8_t)(can_send_hexspinboxes[3]->value()),
(uint8_t)(can_send_hexspinboxes[4]->value()), (uint8_t)(can_send_hexspinboxes[5]->value()),
(uint8_t)(can_send_hexspinboxes[6]->value()), (uint8_t)(can_send_hexspinboxes[7]->value())}));
});
connect(ui->b_clear, &QPushButton::clicked, this, [=, this] { emit can_clear(); });
}
Can_Transceive::~Can_Transceive()
{
delete ui;
}
void Can_Transceive::enable_can_send_data()
{
uint8_t selected = atoi(ui->c_can_send_dlc->currentText().toLocal8Bit());
for (size_t i = 0; i < can_send_hexspinboxes.size(); i++)
{
can_send_hexspinboxes[i]->setEnabled(i < selected);
if (i >= selected)
{
can_send_hexspinboxes[i]->setValue(0);
}
}
}
void Can_Transceive::clear()
{
ui->recvd_list->setRowCount(0);
ui->send_list->setRowCount(0);
}
void Can_Transceive::add_send_item(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload)
{
size_t rc = ui->send_list->rowCount();
ui->send_list->setRowCount(rc + 1);
ui->send_list->setItem(rc, 0, new QTableWidgetItem(QString().setNum(id, 16)));
ui->send_list->setItem(rc, 1, new QTableWidgetItem(QString("%0").arg(dlc)));
for (size_t i = 0; i < dlc; i++)
{
ui->send_list->setItem(rc, 2 + i, new QTableWidgetItem(QString().setNum(payload[i], 16)));
}
ui->send_list->resizeColumnsToContents();
}
void Can_Transceive::add_receive_item(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload)
{
size_t rc = ui->recvd_list->rowCount();
ui->recvd_list->setRowCount(rc + 1);
ui->recvd_list->setItem(rc, 0, new QTableWidgetItem(QString().setNum(id, 16)));
ui->recvd_list->setItem(rc, 1, new QTableWidgetItem(QString("%0").arg(dlc)));
for (size_t i = 0; i < dlc; i++)
{
ui->recvd_list->setItem(rc, 2 + i, new QTableWidgetItem(QString().setNum(payload[i], 16)));
}
ui->recvd_list->resizeColumnsToContents();
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef CAN_TRANSCEIVE_H
#define CAN_TRANSCEIVE_H
#include "hex_spinbox.hpp"
#include <QWidget>
namespace Ui
{
class Can_Transceive;
}
class Can_Transceive : public QWidget
{
Q_OBJECT
public:
explicit Can_Transceive(QWidget *parent = nullptr);
~Can_Transceive();
void enable_can_send_data();
void clear();
void add_send_item(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload);
void add_receive_item(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload);
signals:
void send_can_message(uint32_t id, uint8_t dlc, std::array<uint8_t, 8> payload);
void can_clear();
private:
Ui::Can_Transceive *ui;
std::vector<HexSpinBox *> can_send_hexspinboxes;
};
#endif // CAN_TRANSCEIVE_H
+359
View File
@@ -0,0 +1,359 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Can_Transceive</class>
<widget class="QWidget" name="Can_Transceive">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>713</width>
<height>562</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Received CAN messages</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTableWidget" name="recvd_list">
<column>
<property name="text">
<string>SID</string>
</property>
</column>
<column>
<property name="text">
<string>DLC</string>
</property>
</column>
<column>
<property name="text">
<string>Data 0</string>
</property>
</column>
<column>
<property name="text">
<string>Data 1</string>
</property>
</column>
<column>
<property name="text">
<string>Data 2</string>
</property>
</column>
<column>
<property name="text">
<string>Data 3</string>
</property>
</column>
<column>
<property name="text">
<string>Data 4</string>
</property>
</column>
<column>
<property name="text">
<string>Data 5</string>
</property>
</column>
<column>
<property name="text">
<string>Data 6</string>
</property>
</column>
<column>
<property name="text">
<string>Data 7</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_8">
<property name="title">
<string>Send CAN message</string>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<item row="1" column="1">
<widget class="QComboBox" name="c_can_send_dlc">
<item>
<property name="text">
<string>0</string>
</property>
</item>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>3</string>
</property>
</item>
<item>
<property name="text">
<string>4</string>
</property>
</item>
<item>
<property name="text">
<string>5</string>
</property>
</item>
<item>
<property name="text">
<string>6</string>
</property>
</item>
<item>
<property name="text">
<string>7</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
</widget>
</item>
<item row="1" column="10">
<widget class="QPushButton" name="b_can_send_send">
<property name="text">
<string>Send</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="HexSpinBox" name="s_can_send_data1">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="HexSpinBox" name="s_can_send_sid">
<property name="maximum">
<number>65535</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="HexSpinBox" name="s_can_send_data0">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>SID</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>DLC</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Data 0</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Data 1</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Data 2</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Data 3</string>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Data 4</string>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Data 5</string>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Data 6</string>
</property>
</widget>
</item>
<item row="0" column="9">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Data 7</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="HexSpinBox" name="s_can_send_data2">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="HexSpinBox" name="s_can_send_data3">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="HexSpinBox" name="s_can_send_data4">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="HexSpinBox" name="s_can_send_data5">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="HexSpinBox" name="s_can_send_data6">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="9">
<widget class="HexSpinBox" name="s_can_send_data7">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Send CAN messages</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QTableWidget" name="send_list">
<column>
<property name="text">
<string>SID</string>
</property>
</column>
<column>
<property name="text">
<string>DLC</string>
</property>
</column>
<column>
<property name="text">
<string>Data 0</string>
</property>
</column>
<column>
<property name="text">
<string>Data 1</string>
</property>
</column>
<column>
<property name="text">
<string>Data 2</string>
</property>
</column>
<column>
<property name="text">
<string>Data 3</string>
</property>
</column>
<column>
<property name="text">
<string>Data 4</string>
</property>
</column>
<column>
<property name="text">
<string>Data 5</string>
</property>
</column>
<column>
<property name="text">
<string>Data 6</string>
</property>
</column>
<column>
<property name="text">
<string>Data 7</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="b_clear">
<property name="text">
<string>clear buffers</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>HexSpinBox</class>
<extends>QSpinBox</extends>
<header>hex_spinbox.hpp</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+40
View File
@@ -0,0 +1,40 @@
#include "hex_spinbox.hpp"
HexSpinBox::HexSpinBox(QWidget *parent, bool showPrefix, const QString &format) : QSpinBox(parent), format(format)
{
// Validates hex strings up to 8 chars with or w/out leading "0x" prefix.
// For arbitrary prefix/suffix, the regex could be built dynamically
// in validate(), or override setPrefix()/setSuffix() methods.
const QRegularExpression rx("(?:0[xX])?[0-9A-Fa-f]{1,8}");
validator = new QRegularExpressionValidator(rx, this);
setShowPrefix(showPrefix);
}
void HexSpinBox::setShowPrefix(bool show)
{
if (show)
setPrefix(QStringLiteral("0x"));
else
setPrefix(QString());
}
void HexSpinBox::setFormat(const QString &text)
{
format = text;
this->lineEdit()->setText(textFromValue(value()));
}
QValidator::State HexSpinBox::validate(QString &text, int &pos) const
{
return validator->validate(text, pos);
}
int HexSpinBox::valueFromText(const QString &text) const
{
return text.toInt(0, 16);
}
QString HexSpinBox::textFromValue(int value) const
{
return QString().asprintf(qPrintable(format), value);
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef _HEXSPINBOX_H_
#define _HEXSPINBOX_H_
#include <QLineEdit>
#include <QRegularExpressionValidator>
#include <QSpinBox>
// NOTE: Since QSpinBox uses int as the storage type, the effective editing range
// is +/- 0x7FFF FFFF, so it can't handle a full unsigned int.
// QDoubleSpinBox would be a more suitable base class if a wider range is needed.
class HexSpinBox : public QSpinBox
{
Q_OBJECT
public:
HexSpinBox(QWidget *parent = nullptr, bool showPrefix = false, const QString &format = QStringLiteral("%X"));
public slots:
void setShowPrefix(bool show);
void setFormat(const QString &text);
protected:
QValidator::State validate(QString &text, int &pos) const override;
int valueFromText(const QString &text) const override;
QString textFromValue(int value) const override;
private:
QRegularExpressionValidator *validator;
QString format;
};
#endif // _HEXSPINBOX_H_
+31
View File
@@ -0,0 +1,31 @@
#include "led.hpp"
Led::Led(QWidget *parrent) : QPushButton(parrent)
{
set_read_only(this, true);
}
Led::Led(const QString &text, QWidget *parent)
{
set_read_only(this, true);
}
Led::Led(const QIcon &icon, const QString &text, QWidget *parent)
{
set_read_only(this, true);
}
Led::~Led()
{
}
bool Led::is_read_only(QWidget *widget)
{
return widget->testAttribute(Qt::WA_TransparentForMouseEvents) || (widget->focusPolicy() == Qt::NoFocus);
}
void Led::set_read_only(QWidget *widget, bool read_only)
{
widget->setAttribute(Qt::WA_TransparentForMouseEvents, read_only);
widget->setFocusPolicy(read_only ? Qt::NoFocus : Qt::StrongFocus);
}
+20
View File
@@ -0,0 +1,20 @@
#ifndef LED_H
#define LED_H
#include "QPushButton"
class Led : public QPushButton
{
Q_OBJECT
public:
explicit Led(QWidget *parent = nullptr);
explicit Led(const QString &text, QWidget *parent = nullptr);
Led(const QIcon &icon, const QString &text, QWidget *parent = nullptr);
~Led();
private:
bool is_read_only(QWidget *widget);
void set_read_only(QWidget *widget, bool read_only);
};
#endif // LED_H
+15
View File
@@ -0,0 +1,15 @@
#include "plot_wrapper.hpp"
#include <QPen>
Plot_wrapper::Plot_wrapper(QWidget *parent) : QwtPlot(parent)
{
m_curve = new QwtPlotCurve("Test 1");
m_curve->setPen(QPen(Qt::white));
m_curve->attach(this);
this->replot();
}
QwtPlotCurve *Plot_wrapper::curve() const
{
return m_curve;
}
+20
View File
@@ -0,0 +1,20 @@
#ifndef PLOT_WRAPPER_HPP
#define PLOT_WRAPPER_HPP
#include <QObject>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_text.h>
class Plot_wrapper : public QwtPlot
{
Q_OBJECT
public:
Plot_wrapper(QWidget *parent = nullptr);
QwtPlotCurve *curve() const;
private:
QwtPlotCurve *m_curve;
};
#endif // PLOT_WRAPPER_HPP