使用渐变的方式浏览图片,效果如下:
制作的大概思路为使用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);
}
当点击上一页或下一页时,开启属性动画,动画改编画笔的透明度,从而达到渐变动画的效果。