From: Sergey Date: Wed, 26 Oct 2016 17:20:42 +0000 (+0300) Subject: Qt project for usb relay hid library with simple GUI client (#13) X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=b647ee2abfb3c3c0a743f9c7810f7b6ebcb96e7c;p=usb-relay-hid.git Qt project for usb relay hid library with simple GUI client (#13) * Added Qt interface to Usb Relay Hid - by sergboec 1) Added Qt based solution to build dynamic linked library 2) Added simple Qt Widgets based client to manage devices * [f] beautifying and changes in pro file for linux build --- diff --git a/qt/QUsbRelay/QUsbRelay.pro b/qt/QUsbRelay/QUsbRelay.pro new file mode 100644 index 0000000..3e473aa --- /dev/null +++ b/qt/QUsbRelay/QUsbRelay.pro @@ -0,0 +1,29 @@ +QT -= core gui + +TARGET = usb_relay_device +TEMPLATE = lib +CONFIG += dll + +SOURCES += ../../lib/usb_relay_lib.c +win32{ + SOURCES += ../../commandline/hiddata_mswin.c +} +unix{ + SOURCES += ../../commandline/hiddata_libusb01.c +} + +HEADERS += ../../lib/usb_relay_device.h \ + ../../lib/usb_relay_hw.h \ + ../../commandline/hiddata.h + +INCLUDEPATH += ../../lib/usb-relay-dll/ +INCLUDEPATH += ../../commandline/ + +win32{ + INCLUDEPATH += C:/Program Files (x86)/Windows Kits/8.0/Include/ +} + +unix:{ +CONFIG += link_pkgconfig +PKGCONFIG += libusb +} diff --git a/qt/QUsbRelayGui/QUsbRelayGui.pro b/qt/QUsbRelayGui/QUsbRelayGui.pro new file mode 100644 index 0000000..d2a2e4b --- /dev/null +++ b/qt/QUsbRelayGui/QUsbRelayGui.pro @@ -0,0 +1,38 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-10-02T19:08:35 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = QUsbRelayGui +TEMPLATE = app + + +SOURCES += main.cpp\ + widget.cpp \ + device.cpp + +HEADERS += widget.h \ + device.h + +FORMS += widget.ui \ + device.ui + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../QUsbRelay/release/ -lusb_relay_device +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../QUsbRelay/debug/ -lusb_relay_device +else:unix: LIBS += -L$$OUT_PWD/../QUsbRelay/ -lusb_relay_device + +INCLUDEPATH += $$PWD/../QUsbRelay +DEPENDPATH += $$PWD/../QUsbRelay + +INCLUDEPATH += $$PWD/../../lib +DEPENDPATH += $$PWD/../../lib + +RESOURCES += \ + resources.qrc + +win32: RC_ICONS = device_and_hardware_w.ico diff --git a/qt/QUsbRelayGui/device.cpp b/qt/QUsbRelayGui/device.cpp new file mode 100644 index 0000000..4125f46 --- /dev/null +++ b/qt/QUsbRelayGui/device.cpp @@ -0,0 +1,50 @@ +#include "device.h" +#include "ui_device.h" + +Device::Device(qint16 index, QWidget *parent, QString name, QString serial, quint16 channelCount, QVector status) : + QWidget(parent), + ui(new Ui::device), + _index(index) +{ + ui->setupUi(this); + + ui->device_channel_count_value->setText(QString::number(channelCount)); + ui->device_name_value->setText(name); + ui->device_serial_value->setText(serial); + + connect(ui->device_close_all,&QPushButton::clicked,[this](){ + changeChannelStatus(false); + emit closeAllSignal(this->_index); + }); + + connect(ui->device_open_all,&QPushButton::clicked,[this](){ + changeChannelStatus(true); + emit openAllSignal(this->_index); + }); + + + QVBoxLayout *vbox = new QVBoxLayout; + for(auto i=1;i_index, state,i); + }); + checkBox->setChecked(status[i-1]); + vbox->addWidget(checkBox); + } + + ui->channels_windget->setLayout(vbox); +} + +Device::~Device() +{ + delete ui; +} + +void Device::changeChannelStatus(bool status) +{ + QList allCButtons = this->ui->channels_windget->findChildren(); + for(const auto& i:allCButtons){ + i->setChecked(status); + } +} diff --git a/qt/QUsbRelayGui/device.h b/qt/QUsbRelayGui/device.h new file mode 100644 index 0000000..61f3602 --- /dev/null +++ b/qt/QUsbRelayGui/device.h @@ -0,0 +1,46 @@ +#ifndef DEVICE_H +#define DEVICE_H + +#include +#include +#include +#include + +namespace Ui { +class device; +} + +class Device : public QWidget +{ + Q_OBJECT +public: + explicit Device(qint16 index, QWidget *parent = 0,QString name="", QString serial="", quint16 channelCount=0, QVector status = {}); + ~Device(); +signals: + /*! + * \brief openAllSignal signaling about opening all channels in device with id passed as parameter + */ + void openAllSignal(qint16); + /*! + * \brief closeAllSignal signaling about closing all channels in device with id passed as parameter + */ + void closeAllSignal(qint16); + /*! + * \brief changeChannelState signaling aboud changing state of one channel in device with id passed as parameter + * \param handle device handle + * \param state state open\closed + * \param channel device channel number + */ + void changeChannelState(qint16 handle,bool state,int channel); + +private: + Ui::device *ui; + qint16 _index; + /*! + * \brief changeChannelStatus heper functions - changes view for all channels at device + * \param status + */ + void changeChannelStatus(bool status); +}; + +#endif // DEVICE_H diff --git a/qt/QUsbRelayGui/device.ui b/qt/QUsbRelayGui/device.ui new file mode 100644 index 0000000..80d6532 --- /dev/null +++ b/qt/QUsbRelayGui/device.ui @@ -0,0 +1,98 @@ + + + device + + + + 0 + 0 + 318 + 227 + + + + Form + + + + + + + + Device Name + + + + + + + + + + + + + + Device Serial Number + + + + + + + + + + + + + + Device Channel Count + + + + + + + + + + + + + + + + Open All + + + + + + + Close All + + + + + + + true + + + + + 0 + 0 + 298 + 90 + + + + + + + + + + diff --git a/qt/QUsbRelayGui/device_and_hardware_w.ico b/qt/QUsbRelayGui/device_and_hardware_w.ico new file mode 100644 index 0000000..216154c Binary files /dev/null and b/qt/QUsbRelayGui/device_and_hardware_w.ico differ diff --git a/qt/QUsbRelayGui/main.cpp b/qt/QUsbRelayGui/main.cpp new file mode 100644 index 0000000..3387e67 --- /dev/null +++ b/qt/QUsbRelayGui/main.cpp @@ -0,0 +1,36 @@ +#include +#include + +#include "widget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + qApp->setStyle(QStyleFactory::create("Fusion")); + + QPalette darkPalette; + darkPalette.setColor(QPalette::Window, QColor(53,53,53)); + darkPalette.setColor(QPalette::WindowText, Qt::white); + darkPalette.setColor(QPalette::Base, QColor(25,25,25)); + darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53)); + darkPalette.setColor(QPalette::ToolTipBase, Qt::white); + darkPalette.setColor(QPalette::ToolTipText, Qt::white); + darkPalette.setColor(QPalette::Text, Qt::white); + darkPalette.setColor(QPalette::Button, QColor(53,53,53)); + darkPalette.setColor(QPalette::ButtonText, Qt::white); + darkPalette.setColor(QPalette::BrightText, Qt::red); + darkPalette.setColor(QPalette::Link, QColor(42, 130, 218)); + + darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); + darkPalette.setColor(QPalette::HighlightedText, Qt::black); + + qApp->setPalette(darkPalette); + + qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }"); + + Widget w; + w.show(); + + return a.exec(); +} diff --git a/qt/QUsbRelayGui/resources.qrc b/qt/QUsbRelayGui/resources.qrc new file mode 100644 index 0000000..f56a81d --- /dev/null +++ b/qt/QUsbRelayGui/resources.qrc @@ -0,0 +1,5 @@ + + + device_and_hardware_w.ico + + diff --git a/qt/QUsbRelayGui/widget.cpp b/qt/QUsbRelayGui/widget.cpp new file mode 100644 index 0000000..9df9606 --- /dev/null +++ b/qt/QUsbRelayGui/widget.cpp @@ -0,0 +1,80 @@ +#include "widget.h" +#include "ui_widget.h" + +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::Widget) +{ + ui->setupUi(this); + + list.searchForDevices(); + + for(auto i=0; i< list.m_devices.size();i++){ + + getRelayStatus(i); + + auto dev = list.m_devices[i]; + + //Device has qobject pointer to this and will be deleated by qt system + Device* k = new Device(i,this,dev.m_name,dev.m_serialNumber,dev.m_channelsNumber,dev.m_channelsStatus); + + connect(k,&Device::closeAllSignal,this,&Widget::onSomeonWantCloseAll); + connect(k,&Device::openAllSignal,this,&Widget::onSomeonWantOpenAll); + connect(k,&Device::changeChannelState,this,&Widget::onSomeoneWantToDoAnythingWithChannel); + + QListWidgetItem* j = new QListWidgetItem(); + j->setSizeHint(k->size()); + + listWidgetsVector.push_back(j); + + ui->listWidget->addItem(j); + ui->listWidget->setItemWidget(j,k); + } +} + +Widget::~Widget() +{ + delete ui; + for(auto& i: listWidgetsVector){ + delete i; + } +} + +void Widget::getRelayStatus(int value) +{ + auto handle = usb_relay_device_open(list.m_devices[value].m_raw_pointer); + unsigned int status; + usb_relay_device_get_status(handle,&status); + QVector tmp; + tmp.resize(list.m_devices[value].m_channelsNumber); + for (int j = 0; j < list.m_devices[value].m_channelsNumber ; ++j){ + tmp[j] = 0 != (status & (1 << j)); + } + list.m_devices[value].m_channelsStatus = tmp; + usb_relay_device_close(handle); +} + +void Widget::onSomeonWantCloseAll(qint16 value) +{ + auto handle = usb_relay_device_open(list.m_devices[value].m_raw_pointer); + usb_relay_device_close_all_relay_channel(handle); + usb_relay_device_close(handle); +} + +void Widget::onSomeonWantOpenAll(qint16 value) +{ + auto handle = usb_relay_device_open(list.m_devices[value].m_raw_pointer); + usb_relay_device_open_all_relay_channel(handle); + usb_relay_device_close(handle); +} + +void Widget::onSomeoneWantToDoAnythingWithChannel(qint16 value, bool state, int channel) +{ + auto handle = usb_relay_device_open(list.m_devices[value].m_raw_pointer); + if(state){ + usb_relay_device_open_one_relay_channel(handle,channel); + }else{ + usb_relay_device_close_one_relay_channel(handle,channel); + } + usb_relay_device_close(handle); +} diff --git a/qt/QUsbRelayGui/widget.h b/qt/QUsbRelayGui/widget.h new file mode 100644 index 0000000..86805f8 --- /dev/null +++ b/qt/QUsbRelayGui/widget.h @@ -0,0 +1,109 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "device.h" + +#include + +/*! + * \brief The DeviceInfo class stores anything we need to know about usb relay device + */ +class DeviceInfo{ +public: + DeviceInfo() = default; + DeviceInfo(QString nm, QString sn, quint16 cn, usb_relay_device_info* rp, QString cun): + m_name(nm), + m_serialNumber(sn), + m_channelsNumber(cn), + m_raw_pointer(rp), + m_customName(cun) + { + } + + QString m_name; + QString m_serialNumber; + quint16 m_channelsNumber; + usb_relay_device_info* m_raw_pointer; + QString m_customName; + QVector m_channelsStatus; +}; + +Q_DECLARE_METATYPE(DeviceInfo) + + +class DeviceList +{ +public: + DeviceList() = default; + + void searchForDevices(){ + auto device = usb_relay_device_enumerate(); + if(device == nullptr){ + m_devices.clear(); + return; + } + bool hasNext = true; + while(hasNext){ + m_devices.push_back(DeviceInfo(device->device_path,device->serial_number,device->type,device,"")); + + if(device->next != nullptr){ + device++; + }else{ + hasNext = false; + } + } + } + + ~DeviceList() = default; + + std::vector m_devices; +}; + + +namespace Ui { + class Widget; +} + +/*! + * \brief The Widget class main idea - share device id as an index in DeviceList vector + */ +class Widget : public QWidget +{ + Q_OBJECT + +public: + explicit Widget(QWidget *parent = 0); + ~Widget(); + +private: + Ui::Widget *ui; + DeviceList list; + + QVector listWidgetsVector; + + void getRelayStatus(int); + +private slots: + /*! + * \brief onSomeonWantCloseAll + * \param value device id - see brief of a class + */ + void onSomeonWantCloseAll(qint16 value); + /*! + * \brief onSomeonWantOpenAll + * \param value device id - see brief of a class + */ + void onSomeonWantOpenAll(qint16 value); + void onSomeoneWantToDoAnythingWithChannel(qint16 value,bool state,int channel); + +}; + +#endif // WIDGET_H diff --git a/qt/QUsbRelayGui/widget.ui b/qt/QUsbRelayGui/widget.ui new file mode 100644 index 0000000..b073742 --- /dev/null +++ b/qt/QUsbRelayGui/widget.ui @@ -0,0 +1,31 @@ + + + Widget + + + + 0 + 0 + 400 + 300 + + + + UsbRelayGui + + + + :/images/device_and_hardware_w.ico:/images/device_and_hardware_w.ico + + + + + + + + + + + + + diff --git a/qt/qusbrelayproject.pro b/qt/qusbrelayproject.pro new file mode 100644 index 0000000..fd3a566 --- /dev/null +++ b/qt/qusbrelayproject.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + QUsbRelay \ + QUsbRelayGui