#pragma once #include #include #include #include #include #include #include class QLabel; class QEvent; class QGestureEvent; class QGraphicsPixmapItem; class QGraphicsScene; class QMouseEvent; class QPinchGesture; class QTabBar; class QWheelEvent; // 可缩放、可平移的图片显示控件。 // // 支持两种显示模式: // 1) 单图模式:setImage()/loadImage() 直接显示一张未命名图片,标题栏不显示; // 2) 多图模式:setImages()/setNamedImage() 传入 [名字, 图片] 列表, // 控件顶部用标签页显示名字,下方显示当前选中的图片。 class ImageView : public QGraphicsView { Q_OBJECT public: // 一组“名字 + 图片”,对应多图模式下的一个标签页。 using NamedImage = QPair; explicit ImageView(QWidget* parent = nullptr); ~ImageView() override; void setImage(const QImage& image); void setImage(const QPixmap& pixmap); bool loadImage(const QString& filePath); void clearImage(); // 多图模式:整体替换为指定的一组 [名字, 图片]。 // 若原有当前页的名字仍在新列表中,则继续保持该页;否则显示第一张有图的页。 void setImages(const QVector& images); // 多图模式:新增或更新一张命名图片,其余图片与当前页保持不变。 void setNamedImage(const QString& name, const QImage& image); // 退出多图模式,清空所有命名图片。 void clearImages(); bool isMultiImageMode() const; int imageCount() const; QString imageName(int index) const; QImage namedImage(const QString& name) const; int currentImageIndex() const; void setCurrentImageIndex(int index); bool hasImage() const; QImage image() const; // 比例以原始图片大小为基准,1.0 表示 100%。 double zoomRatio() const; void setZoomRatio(double ratio); void zoomIn(double factor = 1.25); void zoomOut(double factor = 1.25); void resetView(); void setZoomRange(double minimum, double maximum); double minimumZoomRatio() const; double maximumZoomRatio() const; // 图片未铺满视口时的停靠方向,默认居中。 void setImageAlignment(Qt::Alignment alignment); Qt::Alignment imageAlignment() const; signals: void imageChanged(); void zoomRatioChanged(double ratio); // 多图模式下当前标签页发生变化。 void currentImageIndexChanged(int index); protected: bool viewportEvent(QEvent* event) override; void resizeEvent(QResizeEvent* event) override; void wheelEvent(QWheelEvent* event) override; void mousePressEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; void mouseDoubleClickEvent(QMouseEvent* event) override; private: bool handleGestureEvent(QGestureEvent* event); void handlePinchGesture(QPinchGesture* gesture); void updateZoomLabel(); void updateZoomRatio(double ratio, bool keepCenter); void updateZoomRatioAt(double ratio, const QPoint& viewportAnchor); void repositionZoomLabel(); // 显示单张图片;空图片等价于清空当前画面。 void updatePixmap(const QImage& image); // 清空画面,保留多图列表。 void resetScene(); // 按 m_images 刷新标签页标题与可见性,并调整视口边距。 void refreshTabBar(); // 切换到指定标签页并显示对应图片。 void showImageAt(int index); QGraphicsScene* m_scene; QGraphicsPixmapItem* m_pixmapItem; QLabel* m_zoomLabel; QTabBar* m_tabBar; QVector m_images; int m_currentImageIndex; int m_tabBarHeight; bool m_multiImageMode; QImage m_image; double m_zoomRatio; double m_minimumZoomRatio; double m_maximumZoomRatio; Qt::Alignment m_imageAlignment; bool m_panning; bool m_pinching; bool m_needsInitialFit; double m_pinchStartZoomRatio; QPoint m_lastMousePosition; };