当前位置: 首页 > news >正文

网站公司销售怎么做wordpress调用文章方法

网站公司销售怎么做,wordpress调用文章方法,注册公司费用大概多少,仿糗事百科网站源码文章目录 简介1. 整体架构2. 关键类功能概述3. 详细代码实现hikcameraworker.h 和 hikcameraworker.cpp#xff08;海康相机工作线程类#xff09;imageviewerwidget.h 和 imageviewerwidget.cpp#xff08;图像查看部件类#xff09;构造函数 ImageViewerWidget析构函数 ~… 文章目录 简介1. 整体架构2. 关键类功能概述3. 详细代码实现hikcameraworker.h 和 hikcameraworker.cpp海康相机工作线程类imageviewerwidget.h 和 imageviewerwidget.cpp图像查看部件类构造函数 ImageViewerWidget析构函数 ~ImageViewerWidgetupdateImageaddToolActionremoveToolActionmousePressEventmouseMoveEventmouseReleaseEventwheelEventdrawRectanglehandleRightClickMenuzoomInzoomOuttranslateViewstartLineMeasurementcontinueLineMeasurementfinishLineMeasurementupdateLineGeometryisNearLineEndpointgetLineEndpointIndexupdateLineRotationstartCircleMeasurementcontinueCircleMeasurementfinishCircleMeasurementstartRotatedRectMeasurementcontinueRotatedRectMeasurementfinishRotatedRectMeasurementisNearCornergetCornerIndexupdateRectGeometryupdateRectRotationshowLineTooltipshowRectTooltipshowCircleTooltip cameramanager.h 和 cameramanager.cpp相机管理类负责相机业务逻辑mainwindow.h 和 mainwindow.cpp主窗口类main.cpp程序入口4. 功能说明 简介 以下是一个满足需求的 Qt 程序示例采用 C QT语言编写通过合理的分层架构设计实现了界面与业务逻辑的分离具备对多台海康相机的高效控制以及丰富的交互功能 1. 整体架构 程序分为三层界面层负责显示和用户交互、业务逻辑层处理相机相关操作、数据模型层存储相机数据及状态本示例未详细展开可按需扩展。通过信号与槽机制在各层之间传递信息保证模块的低耦合性。 2. 关键类功能概述 CameraInterface定义相机操作的抽象接口确保不同相机厂商实现的兼容性。 HikCameraWorker继承自CameraInterface实现海康相机的具体业务逻辑包括连接、取图、断线重连、手动触发等。MainWindow主窗口类负责创建界面集成菜单栏、工具栏、状态栏、图像显示区和日志区响应用户操作并与业务逻辑层交互。ImageViewerWidget自定义图像显示部件封装 QGraphicsView 和QGraphicsScene负责接收并展示图像数据。 3. 详细代码实现 camerainterface.h相机接口抽象类 #ifndef CAMERAINTERFACE_H #define CAMERAINTERFACE_H#include QObjectclass CameraInterface : public QObject {Q_OBJECT public:virtual ~CameraInterface() {}// 初始化相机返回是否成功virtual bool initialize() 0;// 启动相机图像采集virtual void startCapture() 0;// 停止相机图像采集virtual void stopCapture() 0;// 手动触发一次图像采集virtual void manualTrigger() 0;// 断开相机连接virtual void disconnectCamera() 0;// 获取相机当前连接状态virtual bool isConnected() const 0;signals:// 图像采集成功信号携带图像数据、宽度、高度void imageCaptured(unsigned char* imageData, int width, int height);// 相机出错信号void cameraError(); };#endif // CAMERAINTERFACE_Hhikcameraworker.h 和 hikcameraworker.cpp海康相机工作线程类 // hikcameraworker.h #ifndef HIKCAMERAWORKER_H #define HIKCAMERAWORKER_H#include QObject #include QThread #include MvCameraControl.h #include camerainterface.hclass HikCameraWorker : public CameraInterface {Q_OBJECT public:explicit HikCameraWorker(int cameraIndex, QObject *parent nullptr);~HikCameraWorker();private:int m_cameraIndex;MV_CC_DEVICE_INFO_LIST m_deviceInfoList;MV_CC_DEVICE_INFO* m_pDeviceInfo;MV_CC_HANDLE m_cameraHandle;bool m_isCapturing;bool m_isConnected;bool connectCamera();void disconnectCamera();static void __stdcall imageCallback(MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser);// CameraInterface 接口实现bool initialize() override;void startCapture() override;void stopCapture() override;void manualTrigger() override;void disconnectCamera() override;bool isConnected() const override; };// hikcameraworker.cpp #include hikcameraworker.hHikCameraWorker::HikCameraWorker(int cameraIndex, QObject *parent) :CameraInterface(parent),m_cameraIndex(cameraIndex),m_pDeviceInfo(null nullable),m_cameraHandle(null nullable),m_isCapturing(false),m_isConnected(false) {// 枚举设备MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, m_deviceInfoList);if (m_deviceIdex 0 m_deviceIdex m_deviceInfoList.nDeviceNum) {m_pDeviceInfo m_deviceInfoList.pDeviceInfo[m_deviceIndex];} }HikCameraWorker::~HikCameraWorker() {stopCapture();disconnectCamera(); }bool HikCameraWorker::initialize() {return connectCamera(); }void HikCameraWorker::startCapture() {if (!m_isConnected !connectCamera()) {emit cameraError();return;}m_isCapturing true;MV_CC_SetCallbackFunction(m_cameraHandle, imageCallback, this);MV_CC_StartGrabbing(m_cameraHandle); }void HikCameraWorker::stopCapture() {m_isCapturing false;if (m_cameraHandle) {MV_CC_StopGrabbing(m_cameraHandle);MV_CC_DestroyHandle(m_cameraHandle);m_cameraHandle nullptr;} }void HikCameraWorker::manualTrigger() {if (m_isConnected m_cameraHandle) {MV_CC_SoftwareTriggerCommand(m_cameraHandle);} }bool HikCameraWorker::connectCamera() {if (m_pDeviceInfo) {int nRet MV_CC_CreateHandle(m_cameraHandle, m_pDeviceInfo);if (nRet MV_OK) {nRet MV_CC_OpenDevice(m_cameraHandle);if (nRet MV_OK) {m_isConnected true;return true;} else {MV_CC_DestroyHandle(m_cameraHandle);char errorMsg[1024];MV_CC_GetLastErrorMsg(errorMsg, sizeof(errorMsg));qDebug() Open device error: errorMsg;m_cameraHandle nullptr;}}}return false; }void HikCameraWorker::disconnectCamera() {if (m_cameraHandle) {MV_CC_CloseDevice(m_cameraHandle);MV_CC_DestroyHandle(m_cameraHandle);m_cameraHandle nullptr;}m_isConnected false; }void __stdcall HikCameraWorker::imageCallback(MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser) {HikCameraWorker* worker static_castHikCameraWorker*(pUser);if (worker worker-m_isCapturing) {emit worker-imageCaptured(pFrameInfo-pBuf, pFrameInfo-nWidth, pFrameInfo-nHeight);} }bool HikCameraWorker::isConnected() const {return m_isConnected; }imageviewerwidget.h 和 imageviewerwidget.cpp图像查看部件类 // imageviewerwidget.h #ifndef IMAGEVIEWERWIDGET_H #define IMAGEVIEWERWIDGET_H#include QWidget #include QGraphicsView #include QGraphicsScene #include QMouseEvent #include QWheelEvent #include QGraphicsRectItem #include QGraphicsItemGroup #include QMenu #include QAction #include QDebug #include QPainterPath #include cmath #include QToolTipclass ImageViewerWidget : public QWidget {Q_OBJECT public:explicit ImageViewerWidget(QWidget *parent nullptr);~ImageViewerWidget();// 动态添加工具项到右键菜单例如找线卡尺、圆形卡尺等void addToolAction(QAction* action);// 动态移除工具项void removeToolAction(QAction* action);public slots:void updateImage(unsigned char* imageData, int width, int height);signals:// 当绘制矩形等操作完成后发出信号通知外界例如主窗口携带矩形信息void shapeDrawn(QRectF rect);// 当使用找线卡尺完成测量后发出信号携带线的相关信息起点、终点坐标等void lineMeasured(QPointF start, QPointF end);// 当使用圆形卡尺完成测量后发出信号携带圆的相关信息圆心、半径void circleMeasured(QPointF center, double radius);// 当绘制旋转矩形完成后发出信号携带旋转矩形相关信息矩形、旋转角度void rotatedRectDrawn(QRectF rect, double angle);protected:void mousePressEvent(QMouseEvent* event) override;void mouseMoveEvent(QMouseEvent* event) override;void mouseReleaseEvent(QMouseEvent* event) override;void wheelEvent(QWheelEvent* event) override;private:QGraphicsScene* m_scene;QGraphicsView* m_view;QImage m_image;QGraphicsItemGroup* m_currentItemGroup; // 用于管理当前选中的图形组合如矩形、卡尺等QMenu* m_rightClickMenu;double m_scaleFactor; // 缩放因子// 记录旋转矩形相关状态bool m_isDrawingRotatedRect;QPointF m_rotatedRectStartPoint;QPointF m_rotatedRectLastPoint;double m_rotatedRectRotation;// 正在操作的矩形角索引用于四个角拖拽 -1 表示无操作int m_activeCornerIndex;// 记录矩形中心初始位置用于中心平移QPointF m_rectCenterInitialPos;// 绘制矩形相关函数void drawRectangle(QPointF startPoint, QPointF endPoint);// 处理右键菜单事件void handleRightClickMenu(QMouseEvent* event);// 放大图片void zoomIn();// 缩小图片void zoomOut();// 平移图片void translateView(QPointF offset);// 找线卡尺工具相关函数void startLineMeasurement(QPointF startPoint);// 继续线测量void continueLineMeasurement(QPointF currentPoint);// 完成线测量void finishLineMeasurement(QPointF endPoint);// 圆形卡尺工具相关函数void startCircleMeasurement(QPointF centerPoint);// 继续圆测量void continueCircleMeasurement(QPointF currentPoint);// 完成圆测量void finishCircleMeasurement(QPointF currentPoint);// 旋转矩形工具相关函数void startRotatedRectMeasurement(QPointF startPoint);// 继续旋转矩形测量void continueRotatedRectMeasurement(QPointF currentPoint);// 完成旋转矩形测量void finishRotatedRectMeasurement(QPointF currentPoint);// 辅助函数判断鼠标点击位置是否靠近矩形角bool isNearCorner(QPointF point, QRectF rect, double tolerance 5.0);// 辅助函数更新矩形旋转状态void updateRectRotation(QPointF currentPoint);// 辅助函数根据鼠标移动更新矩形位置和大小void updateRectGeometry(QPointF currentPoint);// 辅助函数显示矩形提示信息void showRectTooltip(QPointF point, QRectF rect); };#endif // IMAGEVIEWERWIDGET_H// imageviewerwidget.cpp #include imageviewerWidget.hImageViewerWidget::ImageViewerWidget(QWidget *parent) :QWidget(parent),m_scaleFactor(1.0),m_isDrawingRotatedRect(false),m_rotatedRectRotation(0),m_activeLineEndpointIndex(-1),m_lineCenterInitialPos(),m_activeCornerIndex(-1),m_rectCenterInitialPos() {m_scene new QGraphicsScene(this);m_view new QGraphicsView(m_scene);m_view-setAlignment(Qt::AlignCenter);m_view-setDragMode(QGraphicsView::ScrollHandDrag); // 开启平移模式m_rightClickMenu new QMenu(this);m_currentItemGroup nullptr;QVBoxLayout* layout new QVBoxLayout(this);layout-addWidget(m_view);setLayout(layout); }ImageViewerWidget::~ImageViewerWidget() {delete m_scene;delete m_view;delete m_rightClickMenu; }void ImageViewerWidget::updateImage(unsigned char* imageData, int width, int height) {m_image QImage(imageData, width, height, QImage::Format_RGB888);m_scene-clear();m_scene-addPixmap(QPixmap::fromImage(m_image));m_view-resetTransform(); // 重置视图变换避免缩放等影响新图像显示m_scaleFactor 1.0;m_isDrawingRotatedRect false; }void ImageViewerWidget::addToolAction(QAction* action) {m_rightClickMenu-addAction(action); }void ImageViewerWidget::removeToolAction(QAction* action) {m_rightClickMenu-removeAction(action); }void ImageViewerWidget::mousePressEvent(QMouseEvent* event) {if (event-button() Qt::RightButton) {handleRightClickMenu(event);} else if (event-button() Qt::LeftButton) {if (!m_currentItemGroup) {m_currentItemGroup new QGraphicsItemGroup;m_scene-addItem(m_currentItemGroup);}if (m_rightClickMenu-actions().contains(findChildQAction*(lineMeasurementAction))) {startLineMeasurement(mapToScene(event-pos()));} else if (m_rightClickMenu-actions().contains(findChildQAction*(circleMeasurementAction))) {startCircleMeasurement(mapToScene(event-pos()));} else if (m_rightClickMenu-actions().contains(findChildQAction*(rotatedRectAction))) {startRotatedRectMeasurement(mapToScene(event-pos()));} else {drawRectangle(mapToScene(event-pos()), mapToScene(event-pos()));}// 检查是否点击在线端点、旋转矩形角上if (m_currentItemGroup) {if (m_rightClickMenu-actions().contains(findChildQAction*(lineMeasurementAction))) {QPainterPath linePath static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front())-path();m_activeLineEndpointIndex getLineEndpointIndex(mapToScene(event-pos()), linePath);if (m_activeLineEndpointIndex! -1) {m_lineCenterInitialPos linePath.boundingRect().center();}}if (m_rightClickMenu-actions().contains(findChildQAction*(rotatedRectAction))) {QRectF rect m_currentItemGroup-boundingRect();m_activeCornerIndex getCornerIndex(mapToScene(event-pos()), rect);if (m_activeCornerIndex! -1) {m_rectCenterInitialPos rect.center();}}}}QWidget::mousePressEvent(event); }void ImageViewerWidget::mouseMoveEvent(QMouseEvent* event) {if (m_currentItemGroup event-buttons() Qt::LeftButton) {QPointF newPos mapToScene(event-pos());QPointF offset newPos - m_currentItemGroup-pos();m_currentItemGroup-moveBy(offset.x(), offset.y());if (m_rightClickMenu-actions().contains(findChildQAction*(lineMeasurementAction))) {continueLineMeasurement(newPos);if (m_activeLineEndpointIndex! -1) {updateLineGeometry(newPos);} else {updateLineRotation(newPos);}} else if (m_rightClickMenu-actions().contains(findChildQAction*(circleMeasurementAction))) {continueCircleMeasurement(newPos);} else if (m_rightClickMenu-actions().contains(findChildQAction*(rotatedRectAction))) {continueRotatedRectMeasurement(newPos);if (m_activeCornerIndex! -1) {updateRectGeometry(newPos);} else {updateRectRotation(newPos);}}// 显示线、矩形或圆的提示信息if (m_rightClickMenu-actions().contains(findChildQAction*(lineMeasurementAction))) {QPainterPath linePath static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front())-path();showLineTooltip(mapToScene(event-pos()), linePath);} else if (m_rightClickMenu-actions().contains(findChildQAction*(rotatedRectAction))) {QRectF rect m_currentItemGroup-boundingRect();showRectTooltip(mapToScene(event-pos()), rect);} else if (m_rightClickMenu-actions().contains(findChildQAction*(circleMeasurementAction))) {QGraphicsPathItem* circleItem static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front());QPainterPath circlePath circleItem-path();showCircleTooltip(mapToScene(event-pos()), circlePath);}}QWidget::mouseMoveEvent(event); }void ImageViewerWidget::mouseReleaseEvent(QMouseEvent* event) {if (m_currentItemGroup event-button() Qt::LeftButton) {if (m_rightClickMenu-actions().contains(findChildQAction*(lineMeasurementAction))) {finishLineMeasurement(mapToScene(event-pos()));m_activeLineEndpointIndex -1;} else if (m_rightClickMenu-actions().contains(findChildQAction*(circleMeasurementAction))) {finishCircleMeasurement(mapToScene(event-pos()));} else if (m_rightClickMenu-actions().contains(findChildQAction*(rotatedRectAction))) {finishRotatedRectMeasurement(mapToScene(event-pos()));m_activeCornerIndex -1;} else {QRectF rect m_currentItemGroup-boundingRect();emit shapeDrawn(rect);}m_currentItemGroup nullptr;}QWidget::mouseReleaseEvent(event); }void ImageViewerWidget::wheelEvent(QWheelEvent* event) {if (event-angleDelta().y() 0) {zoomIn();} else {zoomOut();}QWidget::wheelEvent(event); }void ImageViewerWidget::drawRectangle(QPointF startPoint, QPointF endPoint) {QGraphicsRectItem* rectItem new QGraphicsRectItem(QRectF(startPoint, endPoint));m_currentItemGroup-addToGroup(rectItem); }void ImageViewerWidget::handleRightClickMenu(QMouseEvent* event) {m_rightClickMenu-exec(mapToGlobal(event-pos())); }void ImageViewerWidget::zoomIn() {m_scaleFactor * 1.2;m_view-scale(m_scaleFactor, m_scaleFactor); }void ImageViewerWidget::zoomOut() {m_scaleFactor / 1.2;m_view-scale(m_scaleFactor, m_scaleFactor); }void ImageViewerWidget::translateView(QPointF offset) {m_view-translate(offset.x(), offset.y()); }void ImageViewerWidget::startLineMeasurement(QPointF startPoint) {QGraphicsPathItem* lineItem new QGraphicsPathItem;QPainterPath path;path.moveTo(startPoint);lineItem-setPath(path);m_currentItemGroup-addToGroup(lineItem); }void ImageViewerWidget::continueLineMeasurement(QPointF currentPoint) {QGraphicsPathItem* lineItem static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front());QPainterPath path lineItem-path();path.lineTo(currentPoint);lineItem-setPath(path); }void ImageViewerWidget::finishLineMeasurement(QPointF endPoint) {QGraphicsPathItem* lineItem static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front());QPainterPath path lineItem-path();path.lineTo(endPoint);lineItem-setPath(path);emit lineMeasured(path.elementAt(0).x, path.elementAt(0).y, path.elementAt(path.elementCount() - 1).x, path.elementAt(path.elementCount() - 1).y); }void ImageViewerWidget::updateLineGeometry(QPointF currentPoint) {if (m_currentItemGroup) {QPainterPath linePath static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front())-path();QPointF center linePath.boundingRect().center();QPointF offset currentPoint - m_lineCenterInitialPos;switch (m_activeLineEndpointIndex) {case 0: // 起点linePath.setElementPositionAt(0, linePath.elementAt(0).x offset.x(), linePath.elementAt(0).y offset.y());break;case 1: // 终点linePath.setElementPositionAt(linePath.elementCount() - 1, linePath.elementAt(linePath.elementCount() - 1).x offset.x(), linePath.elementAt(linePath.elementCount() - 1).y offset.y());break;}QGraphicsPathItem* lineItem static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front());lineItem-setPath(linePath);} }bool ImageViewerWidget::isNearLineEndpoint(QPointF point, QPainterPath linePath, double tolerance 5.0) {const QPointF endpoints[2] { QPointF(linePath.elementAt(0).x, linePath.elementAt(0).y), QPointF(linePath.elementAt(linePath.elementCount() - 1).x, linePath.elementAt(linePath.elementCount() - 1).y) };for (int i 0; i 2; i) {if (QLineF(point, endpoints[i]).length() tolerance) {return true;}}return false; }int ImageViewerWidget::getLineEndpointIndex(QPointF point, QPainterPath linePath) {const QPointF endpoints[2] { QPointF(linePath.elementAt(0).x, linePath.elementAt(0).y), QPointF(linePath.elementAt(linePath.elementCount() - 1).x, linePath.elementAt(linePath.elementCount() - 1).y) };for (int i 0; i 2; i) {if (QLineF(point, endpoints[i]).length() 5.0) {return i;}}return -1; }void ImageViewerWidget::updateLineRotation(QPointF currentPoint) {if (m_currentItemGroup) {QPainterPath linePath static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front())-path();double angle std::atan2(currentPoint.y() - linePath.boundingRect().center().y(), currentPoint.x() - linePath.boundingRect().center().x());QGraphicsPathItem* lineItem static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front());lineItem-setRotation(angle * 180 / M_PI);} }void ImageViewerWidget::startCircleMeasurement(QPointF centerPoint) {QGraphicsPathItem* circleItem new QGraphicsPathItem;QPainterPath path;path.addEllipse(centerPoint, 0, 0);circleItem-setPath(path);m_currentItemGroup-addToGroup(circleItem); }void ImageViewerWidget::continueCircleMeasurement(QPointF currentPoint) {QGraphicsPathItem* circleItem static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front());QPainterPath path circleItem-path();double radius std::sqrt(std::pow(currentPoint.x() - path.elementAt(0).x, 2) std::pow(currentPoint.y() - path.elementAt(0).y, 2));path QPainterPath();path.addEllipse(path.elementAt(0).x, path.elementAt(0).y, radius, radius);circleItem-setPath(path); }void ImageViewerWidget::finishCircleMeasurement(QPointF currentPoint) {QGraphicsPathItem* circleItem static_castQGraphicsPathItem*(m_currentItemGroup-childItems().front());QPainterPath path circleItem-path();double radius std::sqrt(std::pow(currentPoint.x() - path.elementAt(0).x, 2) std::pow(currentPoint.y() - path.elementAt(0).y, 2));emit circleMeasured(path.elementAt(0).x, path.elementAt(0).y, radius); }void ImageViewerWidget::startRotatedRectMeasurement(QPointF startPoint) {m_isDrawingRotatedRect true;m_rotatedRectStartPoint startPoint;m_rotatedRectLastPoint startPoint; }void ImageViewerWidget::continueRotatedRectMeasurement(QPointF currentPoint) {if (m_isDrawingRotatedRect) {QGraphicsItemGroup* group m_currentItemGroup;// 先移除之前可能存在的矩形用于实时更新显示QListQGraphicsItem* items group-childItems();for (QGraphicsItem* item : items) {if (QGraphicsRectItem* rectItem qgraphicsitem_castQGraphicsRectItem*(item)) {group-removeFromGroup(rectItem);delete rectItem;}}QRectF rect QRectF(m_rotatedRectStartPoint, currentPoint).normalized();double angle std::atan2(currentPoint.y() - m_rotatedRectStartPoint.y(), currentPoint.x() - m_rotatedRectStartPoint.x());QGraphicsRectItem* rectItem new QGraphicsRectItem(rect);rectItem-setTransformOriginPoint(rect.center());rectItem-setRotation(angle * 180 / M_PI);group-addToGroup(rectItem);m_rotatedRectLastPoint currentPoint;m_rotatedRectRotation angle;} }void ImageViewerWidget::finishRotatedRectMeasurement(QPointF currentPoint) {if (m_isDrawingRotatedRect) {continueRotatedRectMeasurement(currentPoint);QRectF rect QRectF(m_rotatedRectStartPoint, currentPoint).normalized();emit rotatedRectDrawn(rect, m_rotatedRectRotation * 180 / M_PI);m_isDrawingRotatedRect false;} }bool ImageViewerWidget::isNearCorner(QPointF point, QRectF rect, double tolerance 5.0) {const QPointF corners[4] { rect.topLeft(), rect.topRight(), rect.bottomRight(), rect.bottomLeft() };for (int i 0; i 4; i) {if (QLineF(point, corners[i]).length() tolerance) {return true;}}return false; } int ImageViewerWidget::getCornerIndex(QPointF point, QRectF rect) {const QPointF corners[4] { rect.topLeft(), rect.topRight(), rect.bottomRight(), rect.bottomLeft() };for (int i 0; i 4; i) {if (QLineF(point, corners[i]).length() 5.0) {return i;}}return -1; }void ImageViewerWidget::updateRectGeometry(QPointF currentPoint) {if (m_currentItemGroup) {QRectF rect m_currentItemGroup-boundingRect();QPointF center rect.center();QPointF offset currentPoint - m_rectCenterInitialPos;switch (m_activeCornerIndex) {case 0: // 左上角rect.setTopLeft(rect.topLeft() offset);break;case 1: // 右上角rect.setTopRight(rect.topRight() offset);break;case 2: // 右下角rect.setBottomRight(rect.bottomRight() offset);break;case 3: // 左下角rect.setBottomLeft(rect.bottomLeft() offset);break;}QGraphicsRectItem* rectItem static_castQGraphicsRectItem*(m_currentItemGroup-childItems().first());rectItem-setRect(rect);} }void ImageViewerWidget::updateRectRotation(QPointF currentPoint) {if (m_currentItemGroup) {QRectF rect m_currentItemGroup-boundingRect();double angle std::atan2(currentPoint.y() - rect.center().y(), currentPoint.x() - rect.center().x());QGraphicsRectItem* rectItem static_castQGraphicsRectItem*(m_currentItemGroup-childItems().first());rectItem-setRotation(angle * 180 / M_PI);m_rotatedRectRotation angle;} }void ImageViewerWidget::showLineTooltip(QPointF point, QPainterPath linePath) {QPointF start QPointF(linePath.elementAt(0).x, linePath.elementAt(0).y);QPointF end QPointF(linePath.elementAt(linePath.elementCount() - 1).x, linePath.elementAt(linePath.elementCount() - 1).y);QString tooltipText QString(线信息\n起点坐标: (%1, %2)\n终点坐标: (%3, %4)).arg(start.x()).arg(start.y()).arg(end.x()).arg(end.y());QToolTip::showText(mapToGlobal(mapFromScene(point)), tooltipText, this); }void ImageViewerWidget::showRectTooltip(QPointF point, QRectF rect) {QString tooltipText QString(矩形信息\n左上角坐标: (%1, %2)\n右下角坐标: (%3, %4)\n旋转角度: %5°).arg(rect.topLeft().x()).arg(rect.topLeft().y()).arg(rect.bottomRight().x()).arg(rect.bottomRight().y()).arg(m_rotatedRectRotation * 180 / M_PI);QToolTip::showText(mapToGlobal(mapFromScene(point)), tooltipText, this); }void ImageViewerWidget::showCircleTooltip(QPointF point, QPainterPath circlePath) {QPointF center QPointF(circlePath.elementAt(0).x, circlePath.elementAt(0).y);double radius std::sqrt(std::pow(point.x() - center.x, 2) std::pow(point.y() - center.y, 2));QString tooltipText QString(圆信息\n圆心坐标: (%1, %2)\n半径: %3).arg(center.x()).arg(center.y()).arg(radius);QToolTip::showText(mapToGlobal(mapFromScene(point)), tooltipText, this); } 以下是对 ImageViewerWidget.cpp 中各主要函数功能的简单介绍 构造函数 ImageViewerWidget 功能初始化 ImageViewerWidget 类相关的成员变量、创建图形场景 m_scene、图形视图 m_view设置视图平移模式等还初始化右键菜单和用于管理图形组合的指针搭建好界面布局为后续操作做准备。 析构函数 ~ImageViewerWidget 功能释放之前构造函数中创建的 m_scene、m_view、m_rightClickMenu 等资源避免内存泄漏进行清理工作。 updateImage 功能依据传入的图像数据更新显示的图像包括清除原有场景内容、添加新图像、重置视图变换以及相关操作状态变量确保后续操作基于新图像开展。 addToolAction 功能往右键菜单里添加一个工具操作选项QAction可动态扩充右键菜单功能。 removeToolAction 功能从右键菜单中移除指定的工具操作选项QAction实现动态调整菜单内容。 mousePressEvent 功能处理鼠标按下事件右键按下弹出右键菜单左键按下依据右键菜单中的工具选项启动相应图形绘制或测量操作同时判断是否点击在图形关键位置如线端点、矩形角并记录相关信息。 mouseMoveEvent 功能响应鼠标移动且左键按下的情况实现图形的平移根据不同激活工具继续对应图形的绘制或修改操作如更新线、圆、矩形的相关参数还实时显示鼠标悬停处图形的提示信息。 mouseReleaseEvent 功能处理鼠标释放事件针对不同激活工具完成相应操作、重置操作状态并在普通矩形绘制时发送绘制完成信号结束当前操作。 wheelEvent 功能依据鼠标滚轮滚动方向调用相应函数实现图片放大或缩小功能。 drawRectangle 功能创建矩形图形项并添加到当前图形管理组用于在场景中绘制矩形。 handleRightClickMenu 功能在鼠标右键点击位置弹出右键菜单方便选择操作。 zoomIn 功能增大图片的缩放因子实现图片放大显示效果。 zoomOut 功能减小图片的缩放因子让图片缩小显示。 translateView 功能按照传入的偏移量对视图进行平移便于浏览图像不同位置。 startLineMeasurement 功能开启找线卡尺测量创建初始线图形项并添加到管理组准备绘制线。 continueLineMeasurement 功能在找线卡尺测量中随着鼠标移动持续更新线的终点位置动态绘制线。 finishLineMeasurement 功能结束找线卡尺测量确定线的最终形态并发送测量完成信号携带线的起止坐标信息。 updateLineGeometry 功能根据鼠标操作情况更新找线卡尺绘制线的端点位置实现线的拖拽变形。 isNearLineEndpoint 功能判断鼠标位置是否靠近线的端点辅助后续操作判断。 getLineEndpointIndex 功能获取鼠标位置靠近的线端点索引确定操作的具体端点。 updateLineRotation 功能依据鼠标位置改变找线卡尺绘制线的旋转角度实现线的旋转操作。 startCircleMeasurement 功能启动圆形卡尺测量创建初始圆形图形项添加到管理组准备后续绘制圆。 continueCircleMeasurement 功能在圆形卡尺测量中随着鼠标移动更新圆的半径动态绘制圆。 finishCircleMeasurement 功能结束圆形卡尺测量确定圆的最终形态并发送测量完成信号携带圆心和半径信息。 startRotatedRectMeasurement 功能开启旋转矩形绘制操作记录起始点等初始信息。 continueRotatedRectMeasurement 功能在旋转矩形绘制中根据鼠标位置实时更新矩形形状和旋转角度动态展示旋转矩形。 finishRotatedRectMeasurement 功能结束旋转矩形绘制确定最终矩形形态并发送绘制完成信号携带矩形及旋转角度信息。 isNearCorner 功能判断鼠标位置是否靠近矩形的角辅助后续矩形角操作判断。 getCornerIndex 功能获取鼠标位置靠近的矩形角索引确定操作的具体角。 updateRectGeometry 功能依据鼠标对矩形角的操作更新旋转矩形的大小和位置实现角的拖拽改变矩形形态。 updateRectRotation 功能根据鼠标位置更新旋转矩形的旋转角度实现旋转操作。 showLineTooltip 功能在鼠标悬停在线上时显示包含线相关参数起止坐标的提示信息。 showRectTooltip 功能当鼠标悬停在矩形上时展示包含矩形关键参数坐标、旋转角度的提示信息。 showCircleTooltip 功能鼠标悬停在圆上时显示包含圆的圆心和半径等参数的提示信息。 cameramanager.h 和 cameramanager.cpp相机管理类负责相机业务逻辑 // cameramanager.h #ifndef CAMERAMANAGER_H #define CAMERAMANAGER_H#include QObject #include QTimer #include vector #include camerainterface.hclass CameraManager : public QObject {Q_OBJECT public:CameraManager(QObject *parent nullptr);~CameraManager();// 初始化相机列表根据实际连接的相机数量void initializeCameras();// 启动所有相机的图像采集void startCapture();// 停止所有相机的图像采集void stopCapture();// 手动触发所有相机采集一次图像void manualTrigger();// 关闭所有相机连接void closeAllCameras();signals:// 图像采集成功信号携带图像数据、宽度、高度以及相机索引void imageCaptured(unsigned char* imageData, int width, int height, int cameraIndex);// 相机出错信号携带相机索引void cameraError(int cameraIndex);private:std::vectorCameraInterface* m_cameraWorkers;QTimer* m_reconnectionTimer;void setupCameraWorkers(int numCameras);void handleCameraError(int cameraIndex);void checkForReconnection(); };// cameramanager.cpp #include cameramanager.hCameraManager::CameraManager(QObject *parent) :QObject(parent),m_reconnectionTimer(new QTimer(this)) {connect(m_reconnectionTimer, QTimer::timeout, this, CameraManager::checkForReconnection); }CameraManager::~CameraManager() {closeAllCameras();delete m_reconnectionTimer;for (CameraInterface* worker : m_cameraWorkers) {delete worker;} }void CameraManager::initializeCameras() {MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, m_deviceInfoList);int numCameras m_deviceInfoList.nDeviceNum;setupCameraWorkers(numCameras); }void CameraManager::startCapture() {for (CameraInterface* worker : m_cameraWorkers) {QThread* thread new QThread;worker-moveToThread(thread);connect(thread, QThread::started, worker, CameraInterface::startCapture);connect(worker, CameraInterface::destroyed, thread, QThread::quit);connect(thread, QThread::finished, thread, QThread::deleteLater);thread-start();} }void CameraManager::stopCapture() {for (CameraInterface* worker : m_cameraWorkers) {worker-stopCapture();} }void CameraManager::manualTrigger() {for (CameraInterface* worker : m_cameraWorkers) {worker-manualTrigger();} }void CameraManager::closeAllCameras() {for (CameraInterface* worker : m_cameraWorkers) {worker-disconnectCamera();} }void CameraManager::setupCameraWorkers(int numCameras) {m_cameraWorkers.resize(numCameras);for (int i 0; i numCameras; i) {m_cameraWorkers[i] new HikCameraWorker(i);connect(m_cameraWorkers[i], CameraInterface::imageCaptured, this, [this, i](unsigned char* imageData, int width, int height) {emit imageCaptured(imageData, width, height, i);});connect(m_cameraWorkers[i], CameraInterface::cameraError, this, CameraManager::handleCameraError);} }void CameraManager::handleCameraError(int cameraIndex) {m_cameraWorkers[cameraIndex]-stopCapture();m_cameraWorkers[cameraIndex]-disconnectCamera();m_reconnectionTimer-start(5000);emit cameraError(cameraIndex); }void CameraManager::checkForReconnection() {m_reconnectionTimer-stop();for (int i 0; i m_cameraWorkers.size(); i) {if (!m_cameraWorkers[i]-isConnected()) {QThread* thread new QThread;m_cameraWorkers[i]-moveToThread(thread);connect(thread, QThread::started, m_cameraWorkers[i], CameraInterface::startCapture);connect(m_cameraWorkers[i], CameraInterface::destroyed, thread, QThread::quit);connect(thread, QThread::finished, thread, QThread::deleteLater);thread-start();}} }mainwindow.h 和 mainwindow.cpp主窗口类 // mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include QMainWindow #include QMenuBar #include QToolBar #include QStatusBar #include QAction #include QVBoxLayout #include QHBoxLayout #include QLabel #include QTextEdit #include vector #include imageviewerwidget.hclass CameraManager;class MainWindow : public QMainWindow {Q_OBJECT public:MainWindow(QWidget *parent nullptr);~MainWindow();private slots:void onStartCaptureClicked();void onStopCaptureClicked();void updateImage(unsigned char* imageData, int width, int height, int cameraIndex);void handleCameraError(int cameraIndex);void onManualTriggerClicked();void onOpenCameraClicked();void onCloseCameraClicked();void onToggleCameraClicked();private:CameraManager* m_cameraManager;std::vectorImageViewerWidget* m_imageViewers;QMenuBar* m_menuBar;QToolBar* m_toolBar;QStatusBar* m_statusBar;QAction* m_startCaptureAction;QAction* m_stopCaptureAction;QAction* m_manualTriggerAction;QAction* m_openCameraAction;QAction* m_closeCameraAction;QAction* m_toggleCameraAction;QWidget* m_centralWidget;QVBoxLayout* m_layout;QHBoxLayout* m_imageLayout;QTextEdit* m_logTextEdit;void setupMenuBar();void setupToolBar();void setupStatusBar();void setupCameraUI();void addImageViewerWidget();void removeImageViewerWidget(); };#endif // MAINWINDOW_H #endif // MAINWINDOW_H// mainwindow.cpp #include mainwindow.h #include cameramanager.hMainWindow::MainWindow(QWidget *parent) :QMainWindow(parent) {m_cameraManager new CameraManager();m_cameraManager-initializeCameras();setupCameraUI();connect(m_cameraManager, CameraManager::imageCaptured, this, MainWindow::updateImage);connect(m_cameraManager, CameraManager::cameraError, this, MainWindow::handleCameraError); }MainWindow::~MainWindow() {delete m_cameraManager;for (ImageViewerWidget* viewer : m_imageViewers) {delete viewer;} }void MainWindow::setupMenuBar() {m_menuBar new QMenuBar(this);QMenu* cameraMenu m_menuBar-addMenu(相机);m_startCaptureAction cameraMenu-addAction(开始采集);connect(m_startCaptureAction, QAction::triggered, this, MainWindow::onStartCaptureClicked);m_stopCaptureAction cameraMenu-addAction(停止采集);connect(m_stopCaptureAction, QAction::triggered, this, MainWindow::onStopCaptureClicked);m_manualTriggerAction cameraMenu-addAction(手动触发);connect(m_manualTriggerAction, QAction::triggered, this, MainWindow::onManualTriggerClicked);m_openCameraAction cameraMenu-addAction(打开相机);connect(m_openCameraAction, QAction::triggered, this, MainWindow::onOpenCameraClicked);m_closeCameraAction cameraMenu-addAction(关闭相机);connect(m_closeCameraAction, QAction::triggered, this, MainWindow::onCloseCameraClicked);m_toggleCameraAction cameraMenu-addAction(动态开关相机);connect(m_toggleCameraAction, QAction::triggered, this, MainWindow::onToggleCameraClicked);setMenuBar(m_menuBar); }void MainWindow::setupToolBar() {m_toolBar new QToolBar(this);m_toolBar-addAction(m_startCaptureAction);m_toolBar-addAction(m_stopCaptureAction);m_toolBar-addAction(m_manualTriggerAction);m_toolBar-addAction(m_openCameraAction);m_toolBar-addAction(m_closeCameraAction);m_toolBar-addAction(m_toggleCameraAction);addToolBar(m_toolBar); }void MainWindow::setupStatusBar() {m_statusBar new QStatusBar(this);setStatusBar(m_statusBar); }void MainWindow::setupCameraUI() {int numCameras m_cameraManager-getCameraCount();m_imageViewers.resize(numCameras);m_centralWidget new QWidget(this);setCentralWidget(m_centralWidget);m_layout new QVBoxLayout(m_centralWidget);m_imageLayout new QHBoxLayout();m_layout-addLayout(m_imageLayout);m_logTextEdit new QTextEdit(this);m_layout-addWidget(m_logTextEdit);for (int i 0; i numCameras; i) {m_imageViewers[i] new ImageViewerWidget(this);m_imageLayout-addWidget(m_imageViewers[i]);}setupMenuBar();setupToolBar();setupStatusBar(); }void MainWindow::onStartCaptureClicked() {m_cameraManager-startCapture(); }void MainWindow::onStopCaptureClicked() {m_cameraManager-stopCapture(); }void MainWindow::updateImage(unsigned char* imageData, int width, int height, int cameraIndex) {if ( cameraIndex 0 cameraIndex m_imageViewers.size()) {m_imageViewers[cameraIndex]-updateImage(imageData, width, height);} }void MainWindow::handleCameraError(int cameraIndex) {m_logTextEdit-append(相机 QString::number(cameraIndex) 出错); }void MainWindow::onManualTriggerClicked() {m_cameraManager-manualTrigger(); }void MainWindow::onOpenCameraClicked() {m_logTextEdit-append(打开相机操作被触发); }void MainWindow::onCloseCameraClicked() {m_cameraManager-closeAllCameras();m_logTextEdit-append(关闭相机操作被触发); }void MainWindow::onToggleCameraClicked() {if (m_imageViewers.size() m_cameraManager-getCameraCount()) {addImageViewerWidget();} else if (m_imageViewers.size() 0) {removeImageViewerWidget();} }void MainWindow::addImageViewerWidget() {int newIndex m_imageViewers.size();ImageViewerWidget* newWidget new ImageViewerWidget(this);m_imageViewers.push_back(newWidget);m_imageLayout-addWidget(newWidget); }void MainWindow::removeImageViewerWidget() {if (!m_imageViewers.empty()) {int lastIndex m_imageViewers.size() - 1;ImageViewerWidget* widgetToRemove m_imageViewers.back();m_imageViewers.pop_back();m_imageLayout-removeWidget(widgetToRemove);delete widgetToRemove;} }在上述代码中 新增了一个 QAction 用于表示动态开关相机按钮以及对应的槽函数 onToggleCameraClicked。在 onToggleCameraClicked 函数中根据当前显示图片控件数量与相机总数的比较决定是添加还是移除一个 ImageViewerWidget。 addImageViewerWidget 函数用于创建并添加新的图片显示控件到布局中removeImageViewerWidget 函数用于移除最后一个图片显示控件并释放相关资源。通过这些修改实现了动态调整显示图片控件的功能以适配相机的开启与关闭操作。 请注意上述代码基于之前提供的代码框架基础上修改运行时需要确保 CameraManager 类及其他相关依赖正确实现并链接。 main.cpp程序入口 #include QApplication #include mainwindow.hint main(int argc, char *argv[]) {QApplication app(argc, argv);MainWindow window;window.show();return app.exec(); }4. 功能说明 多线程取图每个 HikCameraWorker 运行在独立线程中通过 startCapture 启动相机采集在 imageCallback 回调中发送采集到的图像信号避免阻塞主线程保证界面响应流畅。断线重连当相机出现错误如连接断开触发 cameraError 信号在 handleCameraError 槽函数中停止当前相机取图
http://www.zqtcl.cn/news/149106/

相关文章:

  • 京东网站开发技术织梦网站如何做404
  • 论坛类网站开发屏蔽wordpress缩略图
  • 南宁市两学一做网站logo设计网站官网
  • 中国建设工程造价管理协会网站查询网站开发者的设计构想
  • 华强北网站建设设计素材网站p开头的
  • 怎样让网站快速收录利用数据库修改wordpress密码
  • 网站建设群发广告词做网站首页多少钱
  • 黑彩网站建设中企动力 网站价格
  • 上海营销型网站报价深圳企业网站制作设计
  • 网站清理通知北京电商购物网站
  • 新开传奇网站180合击创建一个个人网站需要多少钱
  • 郑州建网站哪家好深圳企业网站制作公司介绍
  • 企业网站百度收录桂林网站建设价格
  • 砀山做网站的公司wordpress微视频主题
  • 免费的企业网站cms注册网站后邮箱收到邮件
  • 网站推广排名教程怀化职院网站
  • 房产门户网站模板新手做电商怎么起步
  • 成都网站建设科技公沈阳网站建设技术公司排名
  • 自建商城网站上海有哪些网络公司
  • 朋友 合同 网站制作手机网站建设服务商
  • 链接分析属于网站开发棋牌软件开发定制
  • top域名的网站搭建网站步骤
  • 个人网站建设背景和目的海南省网站
  • 山西成宁做的网站义乌网站建设优化排名
  • 东莞网站建设公司辉煌大厦阿里云服务器官方网站
  • 域名注册网站制作自己建网站需要钱吗
  • 东莞市房管局官方网站域名查询ip网站
  • 织梦模板添加网站地图温州做网站掌熊号
  • 怎样凡科建设网站建立网站的步骤
  • 模板类网站建设中国都有哪些网站