This commit is contained in:
2025-10-25 15:45:08 +08:00
parent 86b2015957
commit 351dfdc29b
9 changed files with 129 additions and 109 deletions
+1 -2
View File
@@ -13,7 +13,6 @@
#include <opencv.hpp>
#include <qvariant.h>
enum initStatus{
NotInit,
InitFailure,
@@ -109,7 +108,7 @@ signals:
void sendTriggerManagerLoopData(int loopCounterPerMin,int maxInterval);
void triggerAndCaptureImage(std::string cameraName, std::vector<cv::Mat>* mats);
void getCameraNames(std::vector<std::string>* cameraNames);
private:
explicit qtFuncBridge(QObject* parent = nullptr) : QObject(parent) {}
~qtFuncBridge() = default;
+2 -1
View File
@@ -72,7 +72,8 @@ public slots:
}
camera->captureImage(dataPtr);
int cnt = 0;
while (dataPtr->oriImgs.size() == 0 || cnt < 200) {
while (dataPtr->oriImgs.size() == 0 && cnt < 20) {
QThread::msleep(10);
cnt++;
}
if (dataPtr->oriImgs.size() == 0) {
@@ -73,79 +73,8 @@ public:
this->setFixedHeight(80);
}
// 通用的创建工具按钮函数实现
bool createToolButton(const QString& iconPath, const QString& text,
std::function<void()> clickHandler,
const QSize& buttonSize = QSize(100, 60), const QSize& iconSize = QSize(32, 32)){
// 参数验证
if (iconPath.isEmpty() || text.isEmpty() || !clickHandler) {
return false;
}
// 创建布局
QVBoxLayout* btnLayout = new QVBoxLayout();
if (!btnLayout) {
return false;
}
btnLayout->setSpacing(0);
btnLayout->setContentsMargins(0, 0, 0, 0);
// 使用 QToolButton 来实现图标在上文字在下的效果
QToolButton* btn = new QToolButton(this);
if (!btn) {
delete btnLayout;
return false;
}
// 设置图标,检查图标是否加载成功
QIcon icon(iconPath);
if (icon.isNull()) {
delete btn;
delete btnLayout;
return false;
}
btn->setIcon(icon);
btn->setText(text);
btn->setIconSize(iconSize);
btn->setFixedSize(buttonSize.width(), buttonSize.height()); // 增加高度以容纳文字
btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); // 文字在图标下方
// 设置按钮样式
btn->setStyleSheet(R"(
QToolButton {
background-color: transparent;
border: none;
color: white;
font-family: "微软雅黑";
font-size: 14px;
font-weight: bold;
}
QToolButton:hover {
background-color: black;
border-radius: 5px;
}
)");
btnLayout->addWidget(btn);
btnLayout->setAlignment(Qt::AlignCenter);
// 连接点击事件
if (!connect(btn, &QToolButton::clicked, clickHandler)) {
delete btn;
delete btnLayout;
return false;
}
// 添加到按钮布局容器中
buttonsLayout->addLayout(btnLayout);
return true;
}
bool createToolButton(QIcon icon, const QString& text,
std::function<void()> clickHandler,
std::function<void()> clickHandler, Auth::UserLevel level = Auth::UserLevel::GUEST,
const QSize& buttonSize = QSize(100, 60), const QSize& iconSize = QSize(32, 32)) {
// 参数验证
@@ -197,7 +126,11 @@ public:
btnLayout->setAlignment(Qt::AlignCenter);
// 连接点击事件
if (!connect(btn, &QToolButton::clicked, clickHandler)) {
if (!connect(btn, &QToolButton::clicked, [this, level,clickHandler]() {
m_config->Authorization.executeWithPermission(level, [this, clickHandler]() {
clickHandler();
});
})) {
delete btn;
delete btnLayout;
return false;
@@ -359,7 +292,7 @@ public:
QFont font3("微软雅黑", 10, QFont::Bold);
#pragma region 日志分析按钮
{
_toolBarWidget->createToolButton(":/TongYongUiIcon/TongYongUiIcon/4.LogAnalyze.png",
_toolBarWidget->createToolButton(QIcon(":/TongYongUiIcon/TongYongUiIcon/4.LogAnalyze.png"),
QString::fromStdString(trans.translate("Log")),
[=]() {
emit changeStackWidget(2);
@@ -396,7 +329,7 @@ public:
#pragma endregion
#pragma region 结果图查看按钮
{
_toolBarWidget->createToolButton(":/TongYongUiIcon/TongYongUiIcon/23.1.imageView.png",
_toolBarWidget->createToolButton(QIcon(":/TongYongUiIcon/TongYongUiIcon/23.1.imageView.png"),
QString::fromStdString(trans.translate("ViewImage")),
[=]() {
QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(config->imgSavePath)));
@@ -405,10 +338,9 @@ public:
#pragma endregion
#pragma region 修改检测参数按钮
{
_toolBarWidget->createToolButton(":/TongYongUiIcon/TongYongUiIcon/search_1.png",
_toolBarWidget->createToolButton(QIcon(":/TongYongUiIcon/TongYongUiIcon/search_1.png"),
QString::fromStdString(trans.translate("Param")),
[=]() {
config->Authorization.executeWithPermission(Auth::UserLevel::ADMIN,[this]() {
[this]() {
JsonParamTableEditor* dlg = new JsonParamTableEditor(this);
dlg->setJsonObject(m_config->missionJson["backend"]["missionSettings"]);
dlg->setAttribute(Qt::WA_DeleteOnClose);
@@ -416,14 +348,13 @@ public:
m_config->missionJson["backend"]["missionSettings"] = result;
});
dlg->show();
});
});
}, Auth::UserLevel::ADMIN);
}
#pragma endregion
#pragma region 故障排查按钮
{
_runCommandWidget = new runCommandWidget();
_toolBarWidget->createToolButton(":/TongYongUiIcon/TongYongUiIcon/18.help.png",
_toolBarWidget->createToolButton(QIcon(":/TongYongUiIcon/TongYongUiIcon/18.help.png"),
QString::fromStdString(trans.translate("Debug")),
[=]() {
_runCommandWidget->show();
@@ -431,6 +362,16 @@ public:
});
}
#pragma endregion
#pragma region 九点标定引导按钮
{
_calibration = new calibration();
_toolBarWidget->createToolButton(QIcon(":/TongYongUiIcon/TongYongUiIcon/0.cameraModule.png"),
QString::fromStdString("九点标定"),
[=]() {
_calibration->show();
}, Auth::UserLevel::ADMIN);
}
#pragma endregion
#pragma region 读取bin目录下的tools文件夹并展示
{
std::vector<std::string> files;
@@ -444,16 +385,6 @@ public:
});
}
}
#pragma endregion
#pragma region 九点标定引导按钮
{
_calibration = new calibration();
_toolBarWidget->createToolButton(":/TongYongUiIcon/TongYongUiIcon/0.cameraModule.png",
QString::fromStdString("九点标定"),
[=]() {
_calibration->show();
});
}
#pragma endregion
vLayout->addWidget(_toolBarWidget);
+1 -1
View File
@@ -97,7 +97,7 @@ void MainWindow::initLeftMenuBarComponents() {
//
//配置页面
_settingWidget = new settingWidget(config);
registerPageBar(leftMenuBar::barPositionEnum::bottom, ":/icon/icon/setting.png", u8"配置设置", _settingWidget);
registerPageBar(leftMenuBar::barPositionEnum::bottom, ":/icon/icon/setting.png", u8"配置设置", _settingWidget,Auth::UserLevel::ADMIN);
leftBar->pageBtns[0]->click();
QObject::connect(_displayWidget, &displayWidget::changeStackWidget, this, &MainWindow::switchStackWidget);
+13 -4
View File
@@ -312,11 +312,20 @@ private:
bool setNormalAndMove = false;//判断是否从最大化开始移动
#pragma endregion
#pragma region 窗口切换栏
void registerPageBar(leftMenuBar::barPositionEnum pos,QString iconPath, QString pageDescription, QWidget* page) {
void registerPageBar(leftMenuBar::barPositionEnum pos,QString iconPath, QString pageDescription, QWidget* page, Auth::UserLevel level = Auth::UserLevel::GUEST) {
auto btn = leftBar->registerPageBar(pos,iconPath, pageDescription, page);
connect(btn, &toolBarButton::toolBarButtonClicked, [=](int index) {
switchStackWidget(index);
});
if (level == Auth::UserLevel::GUEST) {
connect(btn, &toolBarButton::toolBarButtonClicked, [=](int index) {
switchStackWidget(index);
});
}
else{
connect(btn, &toolBarButton::toolBarButtonClicked, [=](int index) {
config->Authorization.executeWithPermission(level, [this, index]() {
switchStackWidget(index);
});
});
}
pageWidgets.addWidget(page);
//如果报错请检查Qwidget是否有效
}
@@ -20,6 +20,38 @@
#include <qtBridge.h>
#include <qcombobox.h>
//实时取流线程
class GrabbingThread :public QThread {
public:
GrabbingThread(QLabel* showImageLabelIN,qtFuncBridge* bridgeIn) {
showImageLabel = showImageLabelIN;
bridge = bridgeIn;
}
void setCameraName(std::string cameraNameIN) {
cameraName = cameraNameIN;
}
void run() {
m_runFlag = true;
while (m_runFlag == true){
std::vector<cv::Mat> mats;
emit bridge->triggerAndCaptureImage(cameraName, &mats);
for (auto mat : mats) {
auto pixmap = cvMatToQPixMap(mat);
showImageLabel->setPixmap(pixmap.scaled(showImageLabel->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
}
}
}
void stop() {
m_runFlag = false;
}
private:
bool m_runFlag = false;
QLabel* showImageLabel = nullptr;
std::string cameraName;
qtFuncBridge* bridge = nullptr;
};
//标定数据结构
struct CalibrationData {
int pointNumber;
@@ -302,11 +334,61 @@ private:
class calibration : public QWidget {
Q_OBJECT
public:
GrabbingThread* _GrabbingThread;
calibration() {
this->setWindowTitle("九点标定");
this->setFixedSize(1200, 1000);
this->setFixedSize(1980, 1000);
m_qtFuncBridge = qtFuncBridge::getInstance();
QHBoxLayout* hLayout = new QHBoxLayout(this);
#pragma region 实时取流
QVBoxLayout* vLayout2 = new QVBoxLayout();
QComboBox* cameraSelectBox = new QComboBox();
vLayout2->addWidget(cameraSelectBox, 0, Qt::AlignTop);
QPushButton* refreshCameraBtn = new QPushButton("刷新相机");
vLayout2->addWidget(refreshCameraBtn, 0, Qt::AlignTop);
QPushButton* startGrabbing = new QPushButton("开始取流");
startGrabbing->setDisabled(true);
vLayout2->addWidget(startGrabbing, 0, Qt::AlignTop);
connect(refreshCameraBtn, &QPushButton::clicked, [=]() {
cameraSelectBox->clear();
startGrabbing->setEnabled(true);
std::vector < std::string> cameraNamesVec;
emit m_qtFuncBridge->getCameraNames(&cameraNamesVec);
for (auto cameraName : cameraNamesVec) {
cameraSelectBox->addItem(QString::fromStdString(cameraName));
}
});
QLabel* showNowTimeImageLabel = new QLabel;
vLayout2->addWidget(showNowTimeImageLabel, 1, Qt::AlignTop);
showNowTimeImageLabel->setText("实时取流");
showNowTimeImageLabel->setStyleSheet(" border - radius: 10px; border: 1px solid rgb(70, 75, 80);");
showNowTimeImageLabel->setFixedSize(800, 800);
_GrabbingThread = new GrabbingThread(showNowTimeImageLabel, m_qtFuncBridge);
connect(startGrabbing, &QPushButton::clicked, [=]() {
if (_GrabbingThread->isRunning() == false) {
showNowTimeImageLabel->clear();
_GrabbingThread->setCameraName(cameraSelectBox->currentText().toStdString());
_GrabbingThread->start();
startGrabbing->setText("停止取流");
}
else {
_GrabbingThread->stop();
startGrabbing->setText("开始取流");
}
});
connect(this, &calibration::close, [=]() {
_GrabbingThread->stop();
startGrabbing->setText("开始取流");
});
hLayout->addLayout(vLayout2);
#pragma endregion
#pragma region 主界面
QVBoxLayout* vLayout = new QVBoxLayout();
@@ -490,14 +572,12 @@ public:
connect(m_modifyCoordBtn, &QPushButton::clicked, this, &calibration::modifyCoordinates);//修改坐标按钮
connect(m_retakeCurrentBtn, &QPushButton::clicked, this, &calibration::retakeCurrentPoint);//重新拍摄当前点
connect(m_resetBtn, &QPushButton::clicked, this, &calibration::resetCalibration);//全部重新拍照按钮
#pragma endregion
hLayout->addLayout(vLayout);
#pragma region 实时取流
QVBoxLayout* vLayout2 = new QVBoxLayout();
QComboBox* cameraSelectBox = new QComboBox();
#pragma endregion
m_qtFuncBridge = qtFuncBridge::getInstance();
}
private slots:
+1 -2
View File
@@ -127,9 +127,8 @@ namespace Auth {
}
std::string hashPassword(const std::string& password) {
// 简单的密码哈希实现(实际项目中应该使用更安全的哈希算法如bcrypt)
std::hash<std::string> hasher;
size_t hashValue = hasher(password + "salt_string_2023");
size_t hashValue = hasher(password + "waibibabu_xixihaha");
return std::to_string(hashValue);
}
+3 -1
View File
@@ -170,7 +170,9 @@ void connectSignalAndSlot(appCore* _core, MainWindow* _MainWindow, qtFuncBridge*
_MainWindow->_displayWidget->_softwareDataDisplay, &softwareDataDisplay::onTriggerSateChanged);
QObject::connect(bridge, &qtFuncBridge::triggerAndCaptureImage,
_core->_backEnd.backend, &IBackend::triggerAndCaptureImage);
_core->_backEnd.backend, &IBackend::triggerAndCaptureImage,Qt::DirectConnection);
QObject::connect(bridge, &qtFuncBridge::getCameraNames,
_core->_backEnd.backend, &IBackend::getCameraNames, Qt::DirectConnection);
}
int main(int argc, char* argv[])
@@ -535,7 +535,6 @@ bool Hd_CameraModule_HIK_hard_PCIE::run()
{
n_mutex->unlock();
result = true;
std::cout << "\n gotImg" << std::endl;
break;
}
if (cnt > 120) {