#include "HikWidget.hpp" #include "HikCamera.hpp" #include HikWidget::HikWidget(QWidget *parent) : QWidget(parent) { setWindowTitle("HikVision Camera Control"); resize(1280, 720); // 设置初始窗口大小 initUI(); connectAllSignalsAndSlots(); } void HikWidget::initUI() { // 主布局 - 水平分割 3:1 QHBoxLayout *mainLayout = new QHBoxLayout(this); mainLayout->setContentsMargins(10, 10, 10, 10); mainLayout->setSpacing(15); // 左侧 - QGraphicsView m_pixmapItem = new QGraphicsPixmapItem(); m_scene = new QGraphicsScene(this); m_scene->addItem(m_pixmapItem); m_gv = new QGraphicsView(m_scene, this); m_gv->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_gv->setRenderHint(QPainter::Antialiasing); m_gv->setBackgroundBrush(Qt::darkGray); m_gv->setMinimumSize(640, 480); mainLayout->addWidget(m_gv, 1); // 3:1比例中的3份 // 右侧 - 垂直布局容器 QWidget *rightPanel = new QWidget(this); rightPanel->setFixedWidth(320); // 限制右侧宽度 QVBoxLayout *rightLayout = new QVBoxLayout(rightPanel); rightLayout->setSpacing(15); rightLayout->setContentsMargins(5, 5, 5, 5); // 相机操作GroupBox QGroupBox *cameraGroup = new QGroupBox("相机操作", rightPanel); QGridLayout *cameraLayout = new QGridLayout(cameraGroup); cameraLayout->setSpacing(8); m_btn_openCamera = new QPushButton("打开相机", cameraGroup); m_btn_closeCamera = new QPushButton("关闭相机", cameraGroup); m_btn_startGrabbing = new QPushButton("开始取流", cameraGroup); m_btn_stopGrabbing = new QPushButton("结束取流", cameraGroup); cameraLayout->addWidget(m_btn_openCamera, 0, 0); cameraLayout->addWidget(m_btn_closeCamera, 0, 1); cameraLayout->addWidget(m_btn_startGrabbing, 1, 0); cameraLayout->addWidget(m_btn_stopGrabbing, 1, 1); cameraGroup->setLayout(cameraLayout); // 图像保存GroupBox - 使用2x3表格布局 QGroupBox *saveGroup = new QGroupBox("图像保存", rightPanel); QGridLayout *saveLayout = new QGridLayout(saveGroup); saveLayout->setVerticalSpacing(8); // 设置行间距 saveLayout->setHorizontalSpacing(8); // 设置列间距 saveLayout->setContentsMargins(8, 8, 8, 8); // 设置内边距 m_edit_savePath = new QLineEdit(saveGroup); m_edit_savePath->setReadOnly(true); m_edit_savePath->setPlaceholderText("图像保存路径..."); m_edit_savePath->setClearButtonEnabled(true); m_cmb_imgFormat = new QComboBox(saveGroup); QStringList formats = { ".jpg", ".png", ".tif", ".bmp" }; m_cmb_imgFormat->addItems(formats); m_btn_openDir = new QPushButton("打开...", saveGroup); m_btn_saveImage = new QPushButton("保存", saveGroup); saveLayout->addWidget(m_edit_savePath, 0, 0, 1, 3); // 行0,列0,跨越1行3列 saveLayout->addWidget(m_cmb_imgFormat, 1, 0); saveLayout->addWidget(m_btn_openDir, 1, 1); saveLayout->addWidget(m_btn_saveImage, 1, 2); saveGroup->setLayout(saveLayout); // 相机参数GroupBox QGroupBox *paramGroup = new QGroupBox("相机参数", rightPanel); QGridLayout *paramLayout = new QGridLayout(paramGroup); paramLayout->setVerticalSpacing(10); QLabel *lblExposure = new QLabel("曝光时间:", paramGroup); m_spin_exposureTime = new QDoubleSpinBox(paramGroup); m_spin_exposureTime->setRange(15.0, 9999806.0); m_spin_exposureTime->setValue(10000.0); m_spin_exposureTime->setSingleStep(1.0); m_spin_exposureTime->setSuffix(" us"); m_spin_exposureTime->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); QLabel *lblGain = new QLabel("增益设置:", paramGroup); m_spin_gain = new QDoubleSpinBox(paramGroup); m_spin_gain->setRange(0.0, 23.981199); m_spin_gain->setValue(0.0); m_spin_gain->setSingleStep(0.01); m_spin_gain->setSuffix(" dB"); m_spin_gain->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); paramLayout->addWidget(lblExposure, 0, 0); paramLayout->addWidget(m_spin_exposureTime, 0, 1); paramLayout->addWidget(lblGain, 1, 0); paramLayout->addWidget(m_spin_gain, 1, 1); paramGroup->setLayout(paramLayout); // 添加GroupBox到右侧布局 rightLayout->addWidget(cameraGroup); rightLayout->addWidget(saveGroup); rightLayout->addWidget(paramGroup); rightLayout->addStretch(); // 添加弹性空间 // 添加右侧面板到主布局 mainLayout->addWidget(rightPanel, 1); // 3:1比例中的1份 // 设置按钮初始状态 m_btn_openCamera->setEnabled(true); m_btn_closeCamera->setEnabled(false); m_btn_startGrabbing->setEnabled(false); m_btn_stopGrabbing->setEnabled(false); } void HikWidget::connectAllSignalsAndSlots() { // 相机操作按钮连接 connect(m_btn_openCamera, &QPushButton::clicked, this, [this]() { HikCamera::getInstance().init(); HikCamera::getInstance().registerImageCallback(); m_btn_openCamera->setEnabled(false); m_btn_closeCamera->setEnabled(true); m_btn_startGrabbing->setEnabled(true); m_btn_stopGrabbing->setEnabled(false); }); connect(m_btn_closeCamera, &QPushButton::clicked, this, [this]() { HikCamera::getInstance().deinit(); m_btn_openCamera->setEnabled(true); m_btn_closeCamera->setEnabled(false); m_btn_startGrabbing->setEnabled(false); m_btn_stopGrabbing->setEnabled(false); }); connect(m_btn_startGrabbing, &QPushButton::clicked, this, [this]() { HikCamera::getInstance().startGrabbing(); m_btn_startGrabbing->setEnabled(false); m_btn_stopGrabbing->setEnabled(true); }); connect(m_btn_stopGrabbing, &QPushButton::clicked, this, [this]() { HikCamera::getInstance().stopGrabbing(); m_btn_stopGrabbing->setEnabled(false); m_btn_startGrabbing->setEnabled(true); }); // 图像保存按钮连接 connect(m_btn_openDir, &QPushButton::clicked, this, [this]() { QString dir = QFileDialog::getExistingDirectory( this, "选择保存目录", QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if (!dir.isEmpty()) { m_edit_savePath->setText(QDir::toNativeSeparators(dir)); } }); connect(m_btn_saveImage, &QPushButton::clicked, this, [this]() { QString path = m_edit_savePath->text(); if (path.isEmpty()) { QMessageBox::warning(this, "警告", "请先选择保存路径"); return; } QDir dir(path); if (!dir.exists()) { if (!dir.mkpath(".")) { QMessageBox::critical(this, "错误", "无法创建保存目录"); return; } } // 生成时间戳文件名 yyyy-MM-dd-HH-mm-ss-zzz QDateTime now = QDateTime::currentDateTime(); QString timestamp = now.toString("yyyy-MM-dd-HH-mm-ss-zzz"); QString format = m_cmb_imgFormat->currentText(); QString filePath = QDir::toNativeSeparators( dir.filePath(timestamp + format)); qDebug() << "图片保存路径:" << filePath; }); // 相机参数连接 connect(m_spin_exposureTime, QOverload::of(&QDoubleSpinBox::valueChanged), [](double value) { HikCamera::getInstance().setExposure(value); }); connect(m_spin_gain, QOverload::of(&QDoubleSpinBox::valueChanged), [](double value) { HikCamera::getInstance().setGain(value); }); // 新图像到来 connect(&HikCamera::getInstance(), &HikCamera::newImage, this, [this](const QImage &qimage) { if (qimage.isNull()) { qDebug() << "Qimage invalid"; } m_image = qimage; QPixmap pixmap = QPixmap::fromImage(qimage); m_pixmapItem->setPixmap(pixmap); m_gv->fitInView(m_pixmapItem, Qt::KeepAspectRatio); }, Qt::QueuedConnection); }