使用Qt的Painter绘制图像并显示,根据窗口的大小计算图片显示的尺寸,并可以对图片放大和缩小的显示,还可以对已经放大了的图片进行平移预览的操作。
效果如下:
- 使用函数 painter.translate() 对画布进行平移操作。
- 使用函数 painter.scale() 对画布进行缩放的操作。
完整代码如下:
头文件
#ifndef IMAGE_VIEW_H
#define IMAGE_VIEW_H
#include <QWidget>
#include <QImage>class ImageView : public QWidget
{Q_OBJECTpublic:ImageView(QWidget *parent = nullptr);~ImageView();protected:void contextMenuEvent(QContextMenuEvent *event) override;void paintEvent(QPaintEvent *event) override;void wheelEvent(QWheelEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;private:QImage m_Image;qreal m_ZoomValue = 1.0;int m_XPtInterval = 0;int m_YPtInterval = 0;QPoint m_OldPos;bool m_Pressed = false;private slots:void onLoadImage(void);void onZoomInImage(void);void onZoomOutImage(void);void onPresetImage(void);
};
#endif
源文件:
#include "ImageView.h"
#include <QMenu>
#include <QContextMenuEvent>
#include <QStyleOption>
#include <QPainter>
#include <QFileDialog>ImageView::ImageView(QWidget *parent)
{}ImageView::~ImageView()
{}void ImageView::contextMenuEvent(QContextMenuEvent *event)
{QPoint pos = event->pos();pos = this->mapToGlobal(pos);QMenu *menu = new QMenu(this);QAction *loadImage = new QAction(tr("Load Image"));QObject::connect(loadImage, &QAction::triggered, this, &ImageView::onLoadImage);menu->addAction(loadImage);menu->addSeparator();QAction *zoomInAction = new QAction(tr("Zoom In"));QObject::connect(zoomInAction, &QAction::triggered, this, &ImageView::onZoomInImage);menu->addAction(zoomInAction);QAction *zoomOutAction = new QAction(tr("Zoom Out"));QObject::connect(zoomOutAction, &QAction::triggered, this, &ImageView::onZoomOutImage);menu->addAction(zoomOutAction);QAction *presetAction = new QAction(tr("Preset"));QObject::connect(presetAction, &QAction::triggered, this, &ImageView::onPresetImage);menu->addAction(presetAction);menu->exec(pos);
}void ImageView::paintEvent(QPaintEvent *event)
{// 绘制样式QStyleOption opt;opt.init(this);QPainter painter(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);if (m_Image.isNull())return QWidget::paintEvent(event);// 根据窗口计算应该显示的图片的大小int width = qMin(m_Image.width(), this->width());int height = width * 1.0 / (m_Image.width() * 1.0 / m_Image.height());height = qMin(height, this->height());width = height * 1.0 * (m_Image.width() * 1.0 / m_Image.height());// 平移painter.translate(this->width() / 2 + m_XPtInterval, this->height() / 2 + m_YPtInterval);// 缩放painter.scale(m_ZoomValue, m_ZoomValue);// 绘制图像QRect picRect(-width / 2, -height / 2, width, height);painter.drawImage(picRect, m_Image);
}void ImageView::wheelEvent(QWheelEvent *event)
{int value = event->delta();if (value > 0)onZoomInImage();elseonZoomOutImage();this->update();
}void ImageView::mousePressEvent(QMouseEvent *event)
{m_OldPos = event->pos();m_Pressed = true;
}void ImageView::mouseMoveEvent(QMouseEvent *event)
{if (!m_Pressed)return QWidget::mouseMoveEvent(event);this->setCursor(Qt::SizeAllCursor);QPoint pos = event->pos();int xPtInterval = pos.x() - m_OldPos.x();int yPtInterval = pos.y() - m_OldPos.y();m_XPtInterval += xPtInterval;m_YPtInterval += yPtInterval;m_OldPos = pos;this->update();
}void ImageView::mouseReleaseEvent(QMouseEvent *event)
{m_Pressed = false;this->setCursor(Qt::ArrowCursor);
}void ImageView::onLoadImage(void)
{QString imageFile = QFileDialog::getOpenFileName(this, "Open Image", "./", tr("Images (*.png *.xpm *.jpg)"));QFile file(imageFile);if (!file.exists())return;m_Image.load(imageFile);
}void ImageView::onZoomInImage(void)
{m_ZoomValue += 0.2;this->update();
}void ImageView::onZoomOutImage(void)
{m_ZoomValue -= 0.2;if (m_ZoomValue <= 0){m_ZoomValue += 0.2;return;}this->update();
}void ImageView::onPresetImage(void)
{m_ZoomValue = 1.0;m_XPtInterval = 0;m_YPtInterval = 0;this->update();
}