SmartLockerTools/Analyser/Widget.cpp

288 lines
9.5 KiB
C++
Raw Normal View History

2024-05-21 21:09:55 +08:00
#include "Widget.h"
#include "BoostLog.h"
#include "CategoryLogSinkBackend.h"
2024-05-24 10:23:05 +08:00
#include "Database.h"
2024-05-21 21:09:55 +08:00
#include "ModuleCommunication.h"
2024-05-24 10:23:05 +08:00
#include "PalmFeatureTableModel.h"
2024-05-21 21:09:55 +08:00
#include <QComboBox>
#include <QFormLayout>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QSerialPortInfo>
#include <QTabWidget>
2024-05-24 10:23:05 +08:00
#include <QTableView>
2024-05-21 21:09:55 +08:00
#include <QTextBrowser>
#include <QTimer>
#include <QVBoxLayout>
Widget::Widget(QWidget *parent) : QWidget{parent} {
auto serialGroupBox = new QGroupBox("串口设置");
auto serialLayout = new QGridLayout();
auto label = new QLabel("端口");
serialLayout->addWidget(label, 0, 0);
m_serialComboBox = new QComboBox();
serialLayout->addWidget(m_serialComboBox, 0, 1);
label = new QLabel("波特率");
serialLayout->addWidget(label, 1, 0);
label = new QLabel("115200");
serialLayout->addWidget(label, 1, 1);
auto refreshButton = new QPushButton("刷新");
connect(refreshButton, &QPushButton::clicked, this, &Widget::onSerialRefreshButtonClicked);
m_serialConnectButton = new QPushButton("连接");
connect(m_serialConnectButton, &QPushButton::clicked, this, &Widget::onSerialConnectButtonClicked);
serialLayout->addWidget(refreshButton, 2, 0);
serialLayout->addWidget(m_serialConnectButton, 2, 1);
serialGroupBox->setLayout(serialLayout);
auto connectLayout = new QHBoxLayout();
connectLayout->addWidget(serialGroupBox);
2024-05-22 18:03:11 +08:00
connectLayout->addWidget(initializeUvcGroupBox());
2024-05-21 21:09:55 +08:00
m_logBrowser = new QTextBrowser();
m_logBrowser->setReadOnly(true);
2024-05-22 18:03:11 +08:00
auto logLayout = new QVBoxLayout();
m_logBrowser->setLayout(logLayout);
auto btn = new QPushButton("清空");
connect(btn, &QPushButton::clicked, this, &Widget::onClearLogButtonClicked);
logLayout->addWidget(btn, 0, Qt::AlignBottom | Qt::AlignRight);
2024-05-21 21:09:55 +08:00
2024-05-24 10:23:05 +08:00
m_featureTableView = new QTableView();
2024-05-21 21:09:55 +08:00
auto tabWidget = new QTabWidget();
tabWidget->addTab(m_logBrowser, "日志");
tabWidget->addTab(new QWidget(), "视频流");
2024-05-24 10:23:05 +08:00
tabWidget->addTab(m_featureTableView, "本地特征值列表");
2024-05-21 21:09:55 +08:00
m_commandGroupBox = initializeCommandGroupBox();
auto operatorLayout = new QVBoxLayout();
operatorLayout->addLayout(connectLayout);
operatorLayout->addWidget(m_commandGroupBox);
operatorLayout->addStretch(2);
auto layout = new QHBoxLayout(this);
layout->addLayout(operatorLayout, 1);
layout->addWidget(tabWidget, 3);
m_database = std::make_shared<Database>();
2024-05-24 10:23:05 +08:00
m_featureModel = new PalmFeatureTableModel(this);
m_featureTableView->setModel(m_featureModel);
2024-05-21 21:09:55 +08:00
QTimer::singleShot(0, this, [this]() {
onSerialRefreshButtonClicked();
m_commandGroupBox->setEnabled(false);
if (!m_database->open("database.db")) {
LOG(error) << "open database failed.";
}
2024-05-21 21:09:55 +08:00
});
}
void Widget::initializeLogger() {
auto backend = boost::make_shared<CategoryLogSinkBackend>("GUI", m_logBrowser);
using SynchronousCategorySink = boost::log::sinks::synchronous_sink<CategoryLogSinkBackend>;
auto sink = boost::make_shared<SynchronousCategorySink>(backend);
// sink->set_formatter(&zlogFormatter);
boost::log::core::get()->add_sink(sink);
}
QGroupBox *Widget::initializeCommandGroupBox() {
auto ret = new QGroupBox("命令");
auto layout = new QGridLayout();
layout->addWidget(initializeEnrollGroupBox(), 0, 0);
layout->addWidget(initializeVerifyGroupBox(), 0, 1);
layout->addWidget(initializeDeleteGroupBox(), 1, 0);
layout->addWidget(initializePalmFeatureGroupBox(), 1, 1);
2024-05-23 19:58:36 +08:00
auto resetButton = new QPushButton("复位");
connect(resetButton, &QPushButton::clicked, this, &Widget::onResetButtonClicked);
layout->addWidget(resetButton, 2, 0);
2024-05-21 21:09:55 +08:00
ret->setLayout(layout);
return ret;
}
2024-05-22 18:03:11 +08:00
void Widget::onClearLogButtonClicked() {
m_logBrowser->clear();
}
2024-05-21 21:09:55 +08:00
QGroupBox *Widget::initializeEnrollGroupBox() {
auto ret = new QGroupBox("注册用户");
auto layout = new QFormLayout();
m_enrollNameEdit = new QLineEdit();
layout->addRow("用户姓名:", m_enrollNameEdit);
m_enrollTimeoutEdit = new QLineEdit("10");
layout->addRow("超时时间:", m_enrollTimeoutEdit);
m_enrollButton = new QPushButton("注册");
connect(m_enrollButton, &QPushButton::clicked, this, &Widget::onEnrollButtonClicked);
layout->addRow("", m_enrollButton);
ret->setLayout(layout);
return ret;
}
QGroupBox *Widget::initializeVerifyGroupBox() {
auto ret = new QGroupBox("识别用户");
auto layout = new QFormLayout();
m_verifyTimeoutEdit = new QLineEdit("10");
layout->addRow("超时时间:", m_verifyTimeoutEdit);
m_verifyButton = new QPushButton("识别");
connect(m_verifyButton, &QPushButton::clicked, this, &Widget::onVerifyButtonClicked);
layout->addRow("", m_verifyButton);
ret->setLayout(layout);
return ret;
}
QGroupBox *Widget::initializeDeleteGroupBox() {
auto ret = new QGroupBox("删除用户");
auto layout = new QFormLayout();
m_deleteIdEdit = new QLineEdit("");
layout->addRow("用户ID:", m_deleteIdEdit);
m_deleteButton = new QPushButton("删除");
connect(m_deleteButton, &QPushButton::clicked, this, &Widget::onDeleteButtonClicked);
layout->addRow("", m_deleteButton);
m_deleteAllButton = new QPushButton("删除所有");
connect(m_deleteAllButton, &QPushButton::clicked, this, &Widget::onDeleteAllButtonClicked);
layout->addRow("", m_deleteAllButton);
ret->setLayout(layout);
return ret;
}
QGroupBox *Widget::initializePalmFeatureGroupBox() {
auto ret = new QGroupBox("特征值下发/上报");
auto layout = new QFormLayout();
2024-05-22 18:03:11 +08:00
m_palmFeatureEdit = new QLineEdit("");
layout->addRow("用户ID:", m_palmFeatureEdit);
2024-05-21 21:09:55 +08:00
auto button1 = new QPushButton("特征值上报");
layout->addRow("", button1);
2024-05-22 18:03:11 +08:00
connect(button1, &QPushButton::clicked, this, &Widget::onRequestPalmFeatureButtonClicked);
2024-05-21 21:09:55 +08:00
2024-05-23 19:58:36 +08:00
auto button = new QPushButton("特征值下发");
connect(button, &QPushButton::clicked, this, &Widget::onRegisterPalmFeatureButtonClicked);
layout->addRow("", button);
2024-05-21 21:09:55 +08:00
ret->setLayout(layout);
return ret;
}
2024-05-22 18:03:11 +08:00
QGroupBox *Widget::initializeUvcGroupBox() {
auto ret = new QGroupBox("UVC设置");
auto uvcLayout = new QGridLayout();
auto label = new QLabel("设备名");
uvcLayout->addWidget(label, 0, 0);
auto comboBox = new QComboBox();
uvcLayout->addWidget(comboBox, 0, 1);
auto uvcRefreshButton = new QPushButton("刷新");
auto uvcConnectButton = new QPushButton("连接");
uvcLayout->addWidget(uvcRefreshButton, 1, 0);
uvcLayout->addWidget(uvcConnectButton, 1, 1);
ret->setLayout(uvcLayout);
return ret;
}
void Widget::onNewPalmFeature(const PalmFeature &feature) {
2024-05-24 10:23:05 +08:00
auto palms = m_database->palmFeatures();
if (std::find(palms.cbegin(), palms.cend(), feature) != palms.cend()) {
LOG(warning) << "本地数据库已有相同特征数据。";
return;
}
if (!m_database->addPalmFeature(feature)) {
LOG(error) << "add palm feature failed.";
}
}
2024-05-21 21:09:55 +08:00
void Widget::onSerialConnectButtonClicked() {
auto button = dynamic_cast<QPushButton *>(sender());
if (button == nullptr) return;
auto text = button->text();
if (text == "连接") {
auto portName = m_serialComboBox->currentText();
m_communication = std::make_shared<ModuleCommunication>();
connect(m_communication.get(), &ModuleCommunication::newPalmFeature, this, &Widget::onNewPalmFeature);
2024-05-21 21:09:55 +08:00
bool status = m_communication->open(portName);
if (status) {
m_commandGroupBox->setEnabled(true);
button->setText("关闭");
}
} else if (text == "关闭") {
m_communication.reset();
m_commandGroupBox->setEnabled(false);
button->setText("连接");
}
}
void Widget::onSerialRefreshButtonClicked() {
m_serialComboBox->clear();
auto ports = QSerialPortInfo::availablePorts();
for (auto &port : ports) {
m_serialComboBox->addItem(port.portName());
}
}
2024-05-22 18:03:11 +08:00
void Widget::onUvcRefreshButtonClicked() {
}
2024-05-21 21:09:55 +08:00
void Widget::onEnrollButtonClicked() {
auto name = m_enrollNameEdit->text();
auto timeout = m_enrollTimeoutEdit->text().toInt();
m_communication->enroll(name.toStdString(), timeout);
}
void Widget::onVerifyButtonClicked() {
if (!m_communication) return;
auto timeout = m_verifyTimeoutEdit->text().toInt();
m_communication->verify(timeout);
}
void Widget::onDeleteAllButtonClicked() {
if (!m_communication) return;
m_communication->deleteAll();
}
void Widget::onDeleteButtonClicked() {
if (!m_communication) return;
auto id = m_deleteIdEdit->text().toInt();
m_communication->deleteUser(id);
}
2024-05-22 18:03:11 +08:00
void Widget::onRequestPalmFeatureButtonClicked() {
if (!m_communication) return;
auto id = m_palmFeatureEdit->text().toInt();
m_communication->requestPalmFeature(id);
}
2024-05-23 19:58:36 +08:00
void Widget::onRegisterPalmFeatureButtonClicked() {
if (!m_communication) return;
auto features = m_database->palmFeatures();
if (features.empty()) {
LOG(error) << "feature is empty.";
return;
}
m_communication->enrollPalmFeature(264, features.at(0));
}
void Widget::onResetButtonClicked() {
if (!m_communication) return;
m_communication->reset();
}