Qt渐变方式显示图片

使用渐变的方式浏览图片,效果如下:
渐变方式显示图片

制作的大概思路为使用Qt的属性动画,改变画笔绘制时的透明度,先绘制上一张图片,再绘制要显示的图片。

下面仅贴出本示例的关键代码:

头文件

#include <QPropertyAnimation>

class ImageView : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(float alpha READ alpha WRITE setAlpha)

public:
    ImageView();
    ~ImageView();

private:
    float m_PainterAlpha;
    float alpha(void);
    void setAlpha(float alpha);

    // 背景图片
    QPixmap m_BackgroundPixmap;
    // 动画
    QPropertyAnimation *m_PropertyAnimation = nullptr;
    // 当前要显示的图片
    QPixmap m_CurrentPixmap;

    QWidget *m_ButtonWidget = nullptr;
    QLabel *m_PageTagLabel = nullptr;
    QPushButton *m_PreviousButton = nullptr;
    QPushButton *m_NextButton = nullptr;
}

原文件:

ImageView::ImageView()
{
    // 创建显示界面
    QVBoxLayout *layout = new QVBoxLayout;
    layout->setSpacing(0);
    layout->setMargin(0);
    this->setLayout(layout);

    m_ButtonWidget = new QWidget;
    m_ButtonWidget->setFixedHeight(50);
    QHBoxLayout *m_Layout = new QHBoxLayout(m_ButtonWidget);
    m_PreviousButton = new QPushButton("上一张");
    m_NextButton = new QPushButton("下一张");
    m_PreviousButton->setEnabled(false);
    m_NextButton->setEnabled(false);

    m_PageTagLabel = new QLabel("");
    m_Layout->addWidget(m_PreviousButton);
    m_Layout->addWidget(m_NextButton);
    m_Layout->addWidget(m_PageTagLabel);
    m_Layout->addStretch();

    layout->addWidget(m_ButtonWidget, 0, Qt::AlignBottom);
    // 动画
    m_PropertyAnimation = new QPropertyAnimation(this, "alpha", this);
    m_PropertyAnimation->setStartValue(0.2);
    m_PropertyAnimation->setEndValue(1.0);
    m_PropertyAnimation->setDuration(1200);

    // 连接信号和槽
    QObject::connect(m_PreviousButton, SIGNAL(clicked()), this, SLOT(onPreviousButtonClicked()));
    QObject::connect(m_NextButton, SIGNAL(clicked()), this, SLOT(onNextButtonClicked()));
}

ImageView::~ImageView()
{

}

float ImageView::alpha(void)
{
    return m_PainterAlpha;
}

void ImageView::setAlpha(float alpha)
{
    m_PainterAlpha = alpha;
    this->repaint();
}

void ImageView::paintEvent(QPaintEvent* event)
{
    // 绘制样式
    QStyleOption opt;
    opt.init(this);
    QPainter painter(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);

    int rectHeight = this->height() - 50;
    m_PictureRect.setX(5);
    m_PictureRect.setY(5);
    m_PictureRect.setWidth(this->width() - 10);
    m_PictureRect.setHeight(rectHeight - 10);

    if (!m_CurrentPixmap.isNull())
    {
        QImage image = m_CurrentPixmap.toImage();

        int imageWidth = image.width() > m_PictureRect.width() ? m_PictureRect.width() : image.width();
        int imageHeight = imageWidth / (image.width() * 1.0 / image.height());
        imageHeight = imageHeight > m_PictureRect.height() ? m_PictureRect.height() : imageHeight;
        imageWidth = imageHeight * (image.width() * 1.0 / image.height());

        // 绘制图片
        int xPt = m_PictureRect.x() + (m_PictureRect.width() - imageWidth) * 1.0 / 2;
        int yPt = m_PictureRect.y() + (m_PictureRect.height() - imageHeight) * 1.0 / 2;

        // 绘制背景图片
        if (!m_BackgroundPixmap.isNull())
        {
            painter.setOpacity(1.0 - m_PainterAlpha);
            painter.drawPixmap(QRect(xPt, yPt, imageWidth, imageHeight), m_BackgroundPixmap);
        }

        painter.setOpacity(m_PainterAlpha);
        painter.drawImage(QRect(xPt, yPt, imageWidth, imageHeight), image);
    }
    else
    {
        QTextOption o;
        o.setAlignment(Qt::AlignCenter);
        painter.setPen(QColor(255, 255, 255));
        painter.drawText(this->rect(), "没有加载/生成图像", o);
    }

    return QWidget::paintEvent(event);
}

void ImageView::onPreviousButtonClicked(void)
{
    if (m_PixmapList.isEmpty())
        return;

    if (m_CurrentIndex == 0)
        return;

    m_CurrentIndex--;
    if (m_CurrentIndex < 0)
        m_CurrentIndex = 0;

    m_BackgroundPixmap = m_CurrentPixmap;
    m_PropertyAnimation->stop();
    m_PropertyAnimation->start();

    m_CurrentPixmap = m_PixmapList.at(m_CurrentIndex);
    updateCurrentPage();
    this->repaint();
}

void ImageView::onNextButtonClicked(void)
{
    if (m_PixmapList.isEmpty())
        return;

    if (m_CurrentIndex == m_PixmapList.count() - 1)
        return;

    m_CurrentIndex++;
    if (m_PixmapList.count() <= m_CurrentIndex)
        m_CurrentIndex = m_PixmapList.count() - 1;

    m_BackgroundPixmap = m_CurrentPixmap;
    m_PropertyAnimation->stop();
    m_PropertyAnimation->start();

    m_CurrentPixmap = m_PixmapList.at(m_CurrentIndex);
    updateCurrentPage();
    this->repaint();
}

void ImageView::updateCurrentPage(void)
{
    if (m_PixmapList.count() <= 0)
        return;

    QString nPageString = "共%1页,第%2页";
    nPageString = nPageString.arg(m_PixmapList.count()).arg(m_CurrentIndex + 1);
    m_PageTagLabel->setText(nPageString);
}

当点击上一页或下一页时,开启属性动画,动画改编画笔的透明度,从而达到渐变动画的效果。

猜你喜欢

转载自blog.csdn.net/douzhq/article/details/80658037