一个 Qt 显示图片的控件(继承QWidget,使用QPixmap记录图像,最后在paintEvent进行绘制,可缩放)

2023-06-25,,

Qt 中没有专门显示图片的控件,通常我们会使用QLabel来显示图片。但是QLabel 显示图片的能力还是有点弱。比如不支持图像的缩放一类的功能,使用起来不是很方便。因此我就自己写了个简单的类。

我这个类支持三种图像显示模式,我分别称之为:FIXED_SIZE, CENTRED,AUTO_ZOOM, AUTO_SIZE。

FIXED_SIZE 模式下,显示的图像大小等于图像尺寸乘以缩放因子,如果控件的尺寸小于这个大小则多出的部分被裁切掉。
FIX_SIZE_CENTRED模式与FIXED_SIZE 模式类似,但是,显示的图像居于窗口正中。
AUTO_ZOOM 模式下,显示的图像大小自动适应控件窗口大小。
AUTO_SIZE 模式下,这个控件的尺寸等于图像尺寸乘以缩放因子。

下面是代码:

    #ifndef PICTUREBOX_H
    #define PICTUREBOX_H
    #include <QWidget>
    #include <QImage>
    #include <QPixmap>
    class PictureBox : public QWidget
    {
    Q_OBJECT
    public:
    enum PB_MODE {FIXED_SIZE, FIX_SIZE_CENTRED, AUTO_ZOOM, AUTO_SIZE};
    explicit PictureBox(QWidget *parent = 0);
    void setMode(PB_MODE mode);
    ~PictureBox();
    private:
    QPixmap m_pixmap;
    double m_scale;
    PB_MODE m_mode;
    QBrush m_brush;
    protected:
    void paintEvent(QPaintEvent * event);
    signals:
    public slots:
    bool setImage(QImage &image, double scale = 1.0);
    void setBackground(QBrush brush);
    };
    #endif // PICTUREBOX_H
    #include "picturebox.h"
    #include <QPainter>
    #include <QDebug>
    static const int IMAGE_WIDTH = 160;
    static const int IMAGE_HEIGHT = 120;
    static const QSize IMAGE_SIZE = QSize(IMAGE_WIDTH, IMAGE_HEIGHT);
    PictureBox::PictureBox(QWidget *parent) : QWidget(parent)
    {
    m_pixmap = QPixmap(IMAGE_SIZE);
    m_pixmap.fill();
    m_scale = 1.0;
    m_mode = FIXED_SIZE;
    m_brush = QBrush(Qt::white);
    }
    void PictureBox::setBackground(QBrush brush)
    {
    m_brush = brush;
    update();
    }
    void PictureBox::setMode(PB_MODE mode)
    {
    m_mode = mode;
    if(m_mode == AUTO_SIZE)
    {
    setFixedSize(m_pixmap.size() * m_scale);
    }
    else
    {
    setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
    setMinimumSize(0, 0);
    }
    update();
    }
    bool PictureBox::setImage(QImage &image, double scale)
    {
    if(image.isNull())
    {
    return false;
    }
    m_pixmap = QPixmap::fromImage(image);
    m_scale = qBound(0.01, scale, 100.0);
    if(m_mode == AUTO_SIZE)
    {
    setFixedSize(m_pixmap.size() * m_scale);
    }
    update();
    return true;
    }
    void PictureBox::paintEvent(QPaintEvent * event)
    {
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setBackground(m_brush);
    painter.eraseRect(rect());
    double window_width, window_height;
    double image_width, image_height;
    double r1, r2, r;
    int offset_x, offset_y;
    switch (m_mode)
    {
    case FIXED_SIZE:
    case AUTO_SIZE:
    painter.scale(m_scale, m_scale);
    painter.drawPixmap(0, 0, m_pixmap);
    break;
    case FIX_SIZE_CENTRED:
    window_width = width();
    window_height = height();
    image_width = m_pixmap.width();
    image_height = m_pixmap.height();
    offset_x = (window_width - m_scale * image_width) / 2;
    offset_y = (window_height - m_scale * image_height) / 2;
    painter.translate(offset_x, offset_y);
    painter.scale(m_scale, m_scale);
    painter.drawPixmap(0, 0, m_pixmap);
    break;
    case AUTO_ZOOM:
    window_width = width();
    window_height = height();
    image_width = m_pixmap.width();
    image_height = m_pixmap.height();
    r1 = window_width / image_width;
    r2 = window_height / image_height;
    r = qMin(r1, r2);
    offset_x = (window_width - r * image_width) / 2;
    offset_y = (window_height - r * image_height) / 2;
    painter.translate(offset_x, offset_y);
    painter.scale(r, r);
    painter.drawPixmap(0, 0, m_pixmap);
    break;
    }
    }
    PictureBox::~PictureBox()
    {
    }

AUTO_ZOOM 模式下显示例子如下:

FIXED_SIZE 模式下的例子如下:

FIX_SIZE_CENTRED 模式下的例子如下:

http://blog.csdn.net/liyuanbhu/article/details/46687495

一个 Qt 显示图片的控件(继承QWidget,使用QPixmap记录图像,最后在paintEvent进行绘制,可缩放)的相关教程结束。

《一个 Qt 显示图片的控件(继承QWidget,使用QPixmap记录图像,最后在paintEvent进行绘制,可缩放).doc》

下载本文的Word格式文档,以方便收藏与打印。