#include "Widget.h" #include "Application.h" #include "BoostLog.h" #include "CategoryLogSinkBackend.h" #include "Database.h" #include "ModuleCommunication.h" #include "PalmFeatureTableModel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include 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); m_featureTableView = new QTableView(); auto tabWidget = new QTabWidget(); tabWidget->addTab(m_logBrowser, "日志"); tabWidget->addTab(new QWidget(), "视频流"); tabWidget->addTab(m_featureTableView, "本地特征值列表"); 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_featureModel = new PalmFeatureTableModel(this); m_featureTableView->setModel(m_featureModel); QTimer::singleShot(0, this, [this]() { onSerialRefreshButtonClicked(); m_commandGroupBox->setEnabled(false); }); } 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); auto enrollExButton = new QPushButton("注册(EX)"); connect(enrollExButton, &QPushButton::clicked, this, &Widget::onEnrollExButtonClicked); layout->addRow("", enrollExButton); 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::onSerialConnectButtonClicked() { auto button = dynamic_cast(sender()); if (button == nullptr) return; auto text = button->text(); if (text == "连接") { auto portName = m_serialComboBox->currentText(); auto status = Amass::Singleton::instance()->open(portName, 2000000); if (status) { m_commandGroupBox->setEnabled(true); button->setText("关闭"); } } else if (text == "关闭") { Amass::Singleton::instance()->close(); m_commandGroupBox->setEnabled(false); button->setText("连接"); } } void Widget::onSerialRefreshButtonClicked() { m_serialComboBox->clear(); auto ports = QSerialPortInfo::availablePorts(); for (auto &port : ports) { if (port.description() == "蓝牙链接上的标准串行") continue; m_serialComboBox->addItem(port.portName()); } } void Widget::onUvcRefreshButtonClicked() { } void Widget::onEnrollButtonClicked() { auto module = Amass::Singleton::instance()->module(); if (!module) return; auto name = m_enrollNameEdit->text(); auto timeout = m_enrollTimeoutEdit->text().toInt(); module->enroll(name.toStdString(), timeout); } void Widget::onEnrollExButtonClicked() { auto module = Amass::Singleton::instance()->module(); if (!module) return; auto name = m_enrollNameEdit->text(); auto timeout = m_enrollTimeoutEdit->text().toInt(); module->enrollEx(name.toStdString(), timeout); } void Widget::onVerifyButtonClicked() { auto module = Amass::Singleton::instance()->module(); if (!module) return; auto timeout = m_verifyTimeoutEdit->text().toInt(); module->verify(timeout); } void Widget::onDeleteAllButtonClicked() { auto module = Amass::Singleton::instance()->module(); if (!module) return; module->deleteAll(); } void Widget::onDeleteButtonClicked() { auto module = Amass::Singleton::instance()->module(); if (!module) return; auto id = m_deleteIdEdit->text().toInt(); module->deleteUser(id); } void Widget::onRequestPalmFeatureButtonClicked() { auto module = Amass::Singleton::instance()->module(); if (!module) return; auto id = m_palmFeatureEdit->text().toInt(); module->requestPalmFeature(id); } void Widget::onRegisterPalmFeatureButtonClicked() { auto module = Amass::Singleton::instance()->module(); if (!module) return; // auto features = m_database->palmFeatures(); // if (features.empty()) { // LOG(error) << "feature is empty."; // return; // } // module->enrollPalmFeature(264, features.at(0)); } void Widget::onResetButtonClicked() { auto module = Amass::Singleton::instance()->module(); if (!module) return; module->reset(); } void Widget::onNewLog(const QString &log) { m_logBrowser->append(log); }