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 模式下的样例例如以下: