Qt官方示例:Image Viewer Example(带滚动条的图片查看器)

这个示例演示了一个图片查看器。

构造函数:

ImageViewer::ImageViewer(QWidget *parent)
   : QMainWindow(parent), imageLabel(new QLabel)
   , scrollArea(new QScrollArea)
{
    imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
    imageLabel->setScaledContents(true);//标签将缩放其内容以填充所有可用空间,当启用并且标签显示像素图时,它将缩放像素图以填充可用空间。

    scrollArea->setBackgroundRole(QPalette::Dark);
    scrollArea->setWidget(imageLabel);
    scrollArea->setWidgetResizable(true);
    setCentralWidget(scrollArea);

    createActions();

    resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);//初始尺寸为屏幕尺寸的60%
}

使用QLabel显示图片,QLabel作为一个滚动区域的中心部件。

载入和显示图片:

bool ImageViewer::loadFile(const QString &fileName)
{
    QImageReader reader(fileName);
    reader.setAutoTransform(true);
    const QImage newImage = reader.read();
    if (newImage.isNull())
    {
        QMessageBox::information(this, QGuiApplication::applicationDisplayName(),
                                 tr("无法载入 %1: %2").arg(QDir::toNativeSeparators(fileName), reader.errorString()));
        return false;
    }

    setImage(newImage);
    setWindowFilePath(fileName);
    return true;
}

void ImageViewer::setImage(const QImage &newImage)
{
    image = newImage;
    if (image.colorSpace().isValid())
        image.convertToColorSpace(QColorSpace::SRgb);
    imageLabel->setPixmap(QPixmap::fromImage(image));

    scaleFactor = 1.0;//缩放因子重置

    printAct->setEnabled(true);
    fitToWindowAct->setEnabled(true);
    fitToWindowAct->setChecked(true);
    fitToWindow();
    updateActions();
}

保存图片:

bool ImageViewer::saveFile(const QString &fileName)
{
    QImageWriter writer(fileName);
    if (!writer.write(image))
    {
        QMessageBox::information(this, QGuiApplication::applicationDisplayName(),
                                 tr("无法写入 %1: %2").arg(QDir::toNativeSeparators(fileName), writer.errorString()));
        return false;
    }
    return true;
}

将图像复制到剪贴板和从剪贴板获取图像显示:

void ImageViewer::copy()
{
#ifndef QT_NO_CLIPBOARD
    QGuiApplication::clipboard()->setImage(image);
#endif // !QT_NO_CLIPBOARD
}

#ifndef QT_NO_CLIPBOARD
static QImage clipboardImage()
{
    if (const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData())
    {
        if (mimeData->hasImage())
        {
            const QImage image = qvariant_cast(mimeData->imageData());
            if (!image.isNull())
                return image;
        }
    }
    return QImage();
}
#endif // !QT_NO_CLIPBOARD

void ImageViewer::paste()
{
#ifndef QT_NO_CLIPBOARD
    const QImage newImage = clipboardImage();
    if (newImage.isNull())
    {
        statusBar()->showMessage(tr("剪贴板没有图像数据"));
    }
    else
    {
        setImage(newImage);
        setWindowFilePath(QString());
    }
#endif // !QT_NO_CLIPBOARD
}

设置切换图像是否适应窗口:

void ImageViewer::normalSize()
{
    imageLabel->adjustSize();//根据小部件的内容调整其大小
    scaleFactor = 1.0;
}

void ImageViewer::fitToWindow()
{
    bool fitToWindow = fitToWindowAct->isChecked();//是否设置适合窗口
    scrollArea->setWidgetResizable(fitToWindow);//滚动条区域内的内容自动调整大小
    if (!fitToWindow)
        normalSize();
    updateActions();
}

根据缩放因子缩放图像,实际上是调整QLabel的大小:

void ImageViewer::zoomIn()//放大
{
    scaleImage(1.25);
}

void ImageViewer::zoomOut()//缩小
{
    scaleImage(0.8);
}

void ImageViewer::scaleImage(double factor)
{
    scaleFactor *= factor;
    imageLabel->resize(scaleFactor * imageLabel->pixmap().size());

    adjustScrollBar(scrollArea->horizontalScrollBar(), factor);
    adjustScrollBar(scrollArea->verticalScrollBar(), factor);

    zoomInAct->setEnabled(scaleFactor < 3.0);
    zoomOutAct->setEnabled(scaleFactor > 0.333);
}

//更新滑动条位置
void ImageViewer::adjustScrollBar(QScrollBar *scrollBar, double factor)
{
    scrollBar->setValue(int(factor * scrollBar->value() + ((factor - 1) * scrollBar->pageStep()/2)));
}

打印图片:

void ImageViewer::print()
{
    Q_ASSERT(!imageLabel->pixmap(Qt::ReturnByValue).isNull());
#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)

    QPrintDialog dialog(&printer, this);

    if (dialog.exec())
    {
        QPainter painter(&printer);
        
        QPixmap pixmap = imageLabel->pixmap(Qt::ReturnByValue);
        QRect rect = painter.viewport();//可绘制的范围 == printer.paperRect(QPrinter::DevicePixel);
        QSize size = pixmap.size();//源图片的大小
        size.scale(rect.size(), Qt::KeepAspectRatio);//缩放到一个可用容纳图片的范围
        
        painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
        painter.setWindow(pixmap.rect());
        painter.drawPixmap(0, 0, pixmap);
    }
#endif
}

图片的尺寸和打印的纸张尺寸可能差别比较大,所以打印前缩放了一下,确保图片范围在纸张范围之内:

Qt官方示例:Image Viewer Example(带滚动条的图片查看器)_第1张图片

你可能感兴趣的:(#,QWidget,官方示例,qt)