您当前的位置: 首页 >  qt

龚建波

暂无认证

  • 3浏览

    0关注

    313博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Qt绘制旋转的轮播图

龚建波 发布时间:2021-10-31 23:46:58 ,浏览量:3

前言

目前见的比较多的轮播图有平移和旋转两种方式。平移类似淘宝那种切换幻灯片一样的效果,旋转一般是近大远小,看起来有点3D的感觉。本文代码实现旋转轮播图效果如下:

完整代码链接: https://github.com/gongjianbo/MyTestCode/tree/master/Qt/TestQt_20211029_Swiper

设计思路思路 1.计算坐标

可以现在 3D 场景中设计效果,图片是绕着 Y 轴旋转的,如下图:

由于我们的观察点是固定的,就能拆分成两个平面进行处理:

一个是 xz 组成的旋转轨迹平面,x 对应绘制时的坐标点 x 分量,z 对应绘制时的前后顺序,近大远小,同时 z 值更大的堆叠在上层。可以根据球圆上点坐标的方式根据旋转角度计算 x 和 z 的值。 

另一个是绘制时的 xy 屏幕坐标系,可以直接将 y 在图上居中,x 取上一步获取到的 x 值。要注意的是 Qt 绘制时,原点在左上角,右下角为正方向。

2.切换动画

切换动画可以用 QPropertyAnimation 属性动画来做。

要注意的一个点就是头尾切换时。如果第一个切换到最后一个,可以将当前 index 设置为最后一个 index+1,这样再去减 1 动画就能正常过渡;或者最后一个切换到第一个,可以将当前 index 设置为第一个 index-1,这样再去加 1 动画就能正常过渡。否则可能出现从头逐个切换到最后或者反过来,这明显就破坏了旋转的连续性。

主要实现代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
    Q_PROPERTY(double curIndex READ getCurIndex WRITE setCurIndex NOTIFY curIndexChanged)
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    double getCurIndex() const;
    void setCurIndex(double index);

protected:
    bool event(QEvent *e) override;
    void paintEvent(QPaintEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;

private:
    //计算图片位置
    void calcImagePos();
    //计算按钮位置
    void calcBtnPath();
    //切换到下一个图
    void toPrev();
    //切换到上一个图
    void toNext();

signals:
    void curIndexChanged();

private:
    Ui::MainWindow *ui;

    struct ImageNode{
        QImage img;
        double xf{0};
        double yf{0};
        double zf{0};
    };

    //当前图片列表
    QVector imageList;
    //按钮位置
    QVector btnList;
    //图片z堆叠顺序
    QVector drawList;
    //当前设置的index
    int setIndex{0};
    //属性动画绘制用到的index
    double curIndex{0.0};
    //旋转动画
    QPropertyAnimation animation;
    //自动切换定时器
    QTimer swipTimer;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setMouseTracking(true);

    //界面上放了两个按钮用来前进后退,切换当前图片
    connect(ui->btnPrev,&QPushButton::clicked,this,&MainWindow::toPrev);
    connect(ui->btnNext,&QPushButton::clicked,this,&MainWindow::toNext);

    //随便搞五个色块image当作图片
    int alpha=255;
    QList colors=QList{
            QColor(255,0,0,alpha),
            QColor(0,255,0,alpha),
            QColor(0,0,255,alpha),
            QColor(255,255,0,alpha),
            QColor(0,255,255,alpha) };

    for(int i=0;itype()) {
    case QEvent::HoverMove:{
        QHoverEvent *hover = static_cast(e);
        if(hover){
            //放到哪个按钮上就切换到对应图片
            for(int i=0;ipos()))
                {
                    setIndex=i;
                    animation.stop();
                    animation.setStartValue(getCurIndex());
                    animation.setEndValue((double)setIndex);
                    animation.start();
                    break;
                }
            }
        }
    }
        break;
    default:
        break;
    }
    return QMainWindow::event(e);
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    QPainter painter(this);
    painter.fillRect(rect(),Qt::white);
    if(imageList.isEmpty())
        return;

    //切换两种效果
    if(!ui->checkBox->isChecked())
    {
        painter.save();
        //平移到中心点绘制,便于计算
        painter.translate(width()/2,height()/2);
        for(int i=0;i            
关注
打赏
1655829268
查看更多评论
0.0524s