From b137a11c4b6f39b4ae6233ebe20c4c989c982d6f Mon Sep 17 00:00:00 2001 From: openhands Date: Mon, 30 Jun 2025 13:57:13 +0000 Subject: [PATCH] Initial commit with basic EIS Multiplexer Qt application --- CMakeLists.txt | 30 +++++++++++++++++++ channelwidget.cpp | 49 ++++++++++++++++++++++++++++++ channelwidget.h | 35 ++++++++++++++++++++++ main.cpp | 11 +++++++ mainwindow.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++++ mainwindow.h | 39 ++++++++++++++++++++++++ 6 files changed, 240 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 channelwidget.cpp create mode 100644 channelwidget.h create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..05adc82 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,30 @@ + +cmake_minimum_required(VERSION 3.14) + +# Set the project name +project(eismultiplexer-qt) + +# Set C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Find Qt6 +find_package(Qt6 REQUIRED COMPONENTS Widgets) + +# Add the libeismultiplexer library +add_subdirectory(../libeismultiplexer) + +# Add the application executable +add_executable(eismultiplexer-qt + main.cpp + mainwindow.cpp + mainwindow.h + channelwidget.cpp + channelwidget.h +) + +# Link Qt Widgets +target_link_libraries(eismultiplexer-qt Qt6::Widgets eismultiplexer) + +# Include directories +target_include_directories(eismultiplexer-qt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/channelwidget.cpp b/channelwidget.cpp new file mode 100644 index 0000000..ce2366a --- /dev/null +++ b/channelwidget.cpp @@ -0,0 +1,49 @@ + + + +#include "channelwidget.h" +#include + +ChannelWidget::ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, struct eismultiplexer* multiplexer, + QWidget *parent) + : QWidget(parent), deviceSerial(deviceSerial), channelNumber(channelNumber), multiplexer(multiplexer) +{ + // Create layout + QHBoxLayout* layout = new QHBoxLayout(this); + + // Create label with device serial and channel number + label = new QLabel(QString("Device %1, Channel %2").arg(deviceSerial).arg(channelNumber), this); + layout->addWidget(label); + + // Create checkbox + checkbox = new QCheckBox(this); + layout->addWidget(checkbox); + + // Connect checkbox signal + connect(checkbox, &QCheckBox::toggled, this, &ChannelWidget::onChannelToggled); + + // Set layout + setLayout(layout); +} + +ChannelWidget::~ChannelWidget() +{ + // Nothing to clean up +} + +void ChannelWidget::onChannelToggled(bool checked) +{ + channel_t channelFlag = static_cast(1 << channelNumber); + if (checked) { + if (eismultiplexer_connect_channel(multiplexer, channelFlag) < 0) { + qWarning() << "Failed to connect channel" << channelNumber << "on device" << deviceSerial; + checkbox->setChecked(false); + } + } else { + if (eismultiplexer_disconnect_channel(multiplexer, channelFlag) < 0) { + qWarning() << "Failed to disconnect channel" << channelNumber << "on device" << deviceSerial; + checkbox->setChecked(true); + } + } +} + diff --git a/channelwidget.h b/channelwidget.h new file mode 100644 index 0000000..5a2a6b7 --- /dev/null +++ b/channelwidget.h @@ -0,0 +1,35 @@ + + + +#ifndef CHANNELWIDGET_H +#define CHANNELWIDGET_H + +#include +#include +#include +#include +#include + +class ChannelWidget : public QWidget +{ + Q_OBJECT + +public: + ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, struct eismultiplexer* multiplexer, + QWidget *parent = nullptr); + ~ChannelWidget(); + +private slots: + void onChannelToggled(bool checked); + +private: + uint16_t deviceSerial; + uint16_t channelNumber; + struct eismultiplexer* multiplexer; + QCheckBox* checkbox; + QLabel* label; +}; + +#endif // CHANNELWIDGET_H + + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..6bbb0be --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ + +#include +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MainWindow window; + window.show(); + return app.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..a6da879 --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,76 @@ + + +#include "mainwindow.h" +#include +#include + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) +{ + setupUi(); + enumerateDevices(); +} + +MainWindow::~MainWindow() +{ + // Clean up all channel widgets + for (auto widget : channelWidgets) { + delete widget; + } +} + +void MainWindow::setupUi() +{ + // Create central widget and main layout + centralWidget = new QWidget(this); + mainLayout = new QVBoxLayout(centralWidget); + + // Create scroll area + scrollArea = new QScrollArea(this); + scrollContent = new QWidget(); + scrollLayout = new QVBoxLayout(scrollContent); + + // Set up scroll area properties + scrollArea->setWidget(scrollContent); + scrollArea->setWidgetResizable(true); + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + // Add scroll area to main layout + mainLayout->addWidget(scrollArea); + + // Set central widget + setCentralWidget(centralWidget); + setWindowTitle("EIS Multiplexer Controller"); +} + +void MainWindow::enumerateDevices() +{ + size_t count = 0; + uint16_t* serials = eismultiplexer_list_available_devices(&count); + + if (!serials) { + qWarning() << "No EIS multiplexer devices found"; + return; + } + + for (size_t i = 0; i < count; i++) { + uint16_t serial = serials[i]; + struct eismultiplexer multiplexer; + if (eismultiplexer_connect(&multiplexer, serial) == 0) { + uint16_t channelCount = 0; + if (eismultiplexer_get_channel_count(&multiplexer, &channelCount) == 0) { + for (uint16_t channel = 0; channel < channelCount; channel++) { + ChannelWidget* widget = new ChannelWidget(serial, channel, &multiplexer); + channelWidgets.push_back(widget); + scrollLayout->addWidget(widget); + } + } + eismultiplexer_disconnect(&multiplexer); + } else { + qWarning() << "Failed to connect to device with serial" << serial; + } + } + + free(serials); +} + diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..519cb37 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,39 @@ + + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include "channelwidget.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private: + void enumerateDevices(); + void setupUi(); + + QWidget *centralWidget; + QVBoxLayout *mainLayout; + QScrollArea *scrollArea; + QWidget *scrollContent; + QVBoxLayout *scrollLayout; + + std::vector channelWidgets; +}; + +#endif // MAINWINDOW_H +