281 lines
9.2 KiB
C++
281 lines
9.2 KiB
C++
#include "Widget.h"
|
|
#include "BoostLog.h"
|
|
#include "CategoryLogSinkBackend.h"
|
|
#include "ModuleCommunication.h"
|
|
#include <QComboBox>
|
|
#include <QFormLayout>
|
|
#include <QGridLayout>
|
|
#include <QGroupBox>
|
|
#include <QLabel>
|
|
#include <QLineEdit>
|
|
#include <QPushButton>
|
|
#include <QSerialPortInfo>
|
|
#include <QTabWidget>
|
|
#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);
|
|
connectLayout->addWidget(initializeUvcGroupBox());
|
|
|
|
m_logBrowser = new QTextBrowser();
|
|
m_logBrowser->setReadOnly(true);
|
|
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);
|
|
|
|
auto tabWidget = new QTabWidget();
|
|
tabWidget->addTab(m_logBrowser, "日志");
|
|
tabWidget->addTab(new QWidget(), "视频流");
|
|
tabWidget->addTab(new QWidget(), "已注册列表");
|
|
|
|
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>();
|
|
|
|
QTimer::singleShot(0, this, [this]() {
|
|
onSerialRefreshButtonClicked();
|
|
m_commandGroupBox->setEnabled(false);
|
|
if (!m_database->open("database.db")) {
|
|
LOG(error) << "open database failed.";
|
|
}
|
|
});
|
|
}
|
|
|
|
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);
|
|
|
|
auto resetButton = new QPushButton("复位");
|
|
connect(resetButton, &QPushButton::clicked, this, &Widget::onResetButtonClicked);
|
|
layout->addWidget(resetButton, 2, 0);
|
|
|
|
ret->setLayout(layout);
|
|
return ret;
|
|
}
|
|
|
|
void Widget::onClearLogButtonClicked() {
|
|
m_logBrowser->clear();
|
|
}
|
|
|
|
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();
|
|
|
|
m_palmFeatureEdit = new QLineEdit("");
|
|
layout->addRow("用户ID:", m_palmFeatureEdit);
|
|
|
|
auto button1 = new QPushButton("特征值上报");
|
|
layout->addRow("", button1);
|
|
connect(button1, &QPushButton::clicked, this, &Widget::onRequestPalmFeatureButtonClicked);
|
|
|
|
auto button = new QPushButton("特征值下发");
|
|
connect(button, &QPushButton::clicked, this, &Widget::onRegisterPalmFeatureButtonClicked);
|
|
layout->addRow("", button);
|
|
|
|
ret->setLayout(layout);
|
|
|
|
return ret;
|
|
}
|
|
|
|
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) {
|
|
if (!m_database->addPalmFeature(feature)) {
|
|
LOG(error) << "add palm feature failed.";
|
|
}
|
|
|
|
auto palms = m_database->palmFeatures();
|
|
for (auto &p : palms) {
|
|
LOG(info) << p.id << " " << p.username << " " << p.feature.size();
|
|
}
|
|
}
|
|
|
|
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);
|
|
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());
|
|
}
|
|
}
|
|
|
|
void Widget::onUvcRefreshButtonClicked() {
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void Widget::onRequestPalmFeatureButtonClicked() {
|
|
if (!m_communication) return;
|
|
auto id = m_palmFeatureEdit->text().toInt();
|
|
m_communication->requestPalmFeature(id);
|
|
}
|
|
|
|
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();
|
|
}
|