首页 > 其他分享 >Qt编写网易云界面 (4) -----轮播图的实现

Qt编写网易云界面 (4) -----轮播图的实现

时间:2023-08-23 15:33:50浏览次数:31  
标签:Qt PictureWidget int void BtnGroup ui ----- include 轮播

今天主要是完成一下中间部分的第一页效果如图:

image-20230821195356745

ps:轮播图实在是不会,网上找了个大佬的先用着在说。链接

另外还加了换肤功能,当然只是简单的纯色皮肤,如图:

image-20230821195855247

UI设计:

image-20230821214654631

changecolorform.h

#ifndef CHANGECOLORFORM_H
#define CHANGECOLORFORM_H

#include <QWidget>

namespace Ui {
class ChangeColorForm;
}

class ChangeColorForm : public QWidget
{
    Q_OBJECT

public:
    explicit ChangeColorForm(QWidget *parent = nullptr);
    ~ChangeColorForm();
protected:
    void leaveEvent(QEvent *event);
private slots:
    void on_ptnRed_clicked();

    void on_ptnBlue_clicked();

    void on_ptnPink_clicked();


    void on_ptnOrange_clicked();

    void on_ptnYellow_clicked();

    void on_ptnGreen_clicked();

private:
    Ui::ChangeColorForm *ui;
};

#endif // CHANGECOLORFORM_H

changecolorform.cpp:

#include "changecolorform.h"
#include "ui_changecolorform.h"
#include "loadfileqss.h"
ChangeColorForm::ChangeColorForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ChangeColorForm)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_StyledBackground); //设置样式表
    this->setStyleSheet("QWidget{border:1px; background:rgb(255,255,255); border-radius:8px;}"
                        "QWidget:hover{background:rgb(255,255,255);}");
    ui->ptnRed->setStyleSheet("QPushButton{background:rgb(236,65,65); border:0px;}");
    ui->ptnBlue->setStyleSheet("QPushButton{background:rgb(57,175,234);border:0px;}");
    ui->ptnPink->setStyleSheet("QPushButton{background:rgb(255,122,158);border:0px;}");
    ui->ptnOrange->setStyleSheet("QPushButton{background:rgb(226,171,18);border:0px;}");
    ui->ptnYellow->setStyleSheet("QPushButton{background:rgb(249,238,90);border:0px;}");
    ui->ptnGreen->setStyleSheet("QPushButton{background:rgb(106,204,25);border:0px;}");
}

ChangeColorForm::~ChangeColorForm()
{
    delete ui;
}

void ChangeColorForm::leaveEvent(QEvent *event)
{
    Q_UNUSED(event);
    this->close();
}

void ChangeColorForm::on_ptnRed_clicked()
{

     LoadFileQss::setStyle("./FileColorQSS/Red.qss"); //加载qss 样式表,用静态方式
}

void ChangeColorForm::on_ptnBlue_clicked()
{
     LoadFileQss::setStyle("./FileColorQSS/Blue.qss"); //加载qss 样式表,用静态方式
}


void ChangeColorForm::on_ptnPink_clicked()
{
     LoadFileQss::setStyle("./FileColorQSS/Pink.qss"); //加载qss 样式表,用静态方式
}

void ChangeColorForm::on_ptnOrange_clicked()
{
    LoadFileQss::setStyle("./FileColorQSS/Orange.qss"); //加载qss 样式表,用静态方式
}

void ChangeColorForm::on_ptnYellow_clicked()
{
    LoadFileQss::setStyle("./FileColorQSS/Yellow.qss"); //加载qss 样式表,用静态方式
}

void ChangeColorForm::on_ptnGreen_clicked()
{
    LoadFileQss::setStyle("./FileColorQSS/Green.qss"); //加载qss 样式表,用静态方式
}

picturewidget UI:

image-20230821221146496

picturewidget.h:

#ifndef PICTUREWIDGET_H
#define PICTUREWIDGET_H

#include <QWidget>
#include <QButtonGroup>
#include <QGraphicsScene>
#define RAW_VIEW_SIZE QSize(750,198)
#define SCALE_VIEW_PIXMAP (qreal)1/1 //View与图片比例
#define SCALE_BIG_SMALL (qreal)1/1 //图片大小比例
//P1-P10,10个位置,根据需要改动
#define P1 (qreal)0.00
#define P2 (qreal)0.15
#define P3 (qreal)0.44
#define P4 (qreal)0.15
#define P5 (qreal)0.15
#define P6 (qreal)0.15
#define P7 P2
#define P8 P2
#define P9 P2
#define P10 P2
#define MID_TYPE 1
#define FPS 60//帧数,每秒
#define DURATION_MS 500//移动一次图元经过时间,毫秒,不得低于帧数

namespace Ui {
class PictureWidget;
}

class PictureWidget : public QWidget
{
    Q_OBJECT

public:
    enum Rules:int{
        RuleA = 1,
        RuleB = -1,
        RuleC = 2,
        RuleD = -2
    };
    explicit PictureWidget(QWidget *parent = nullptr);
    ~PictureWidget();
    void setButtonGroup();  //设置button组
    void setInitList(); //设置相关图片信息
    void setPictureScreen(); //
    void setTimerAndConnect(); //设置定时器与
    int getIndexByRules(int oldIndex,int rule);
    template<typename T>
    void rollList(QList<T> &oldList, int dir, int count);
    void rollItem(int rollDir,unsigned rollCount);
    int  getrightN(int num); //获取准确的位置
public slots:
     void timerOutFunc();
     void clickedItemRoll(int type);
private slots:
     void on_btnL_clicked();

     void on_btnR_clicked();

private:
    Ui::PictureWidget *ui;
    QTimer *m_timer; //定时器
    QGraphicsScene *m_scene; //场景
//    PictrueView *m_view; //视图
    QLineF m_MidLine; //中等线,确定图片位置
    QList<qreal> m_PointList; //各个图片位置信息
    QList<QPixmap> m_PixmapList; //各个图片列表
    QList<qreal> m_ZValueList; //各个显示优先级列表
    QList<qreal> m_PixmapScaleList; //各个图片位置信息伸缩因子列表
    int m_index;
    Rules m_currentRule; //当前执行的类型操作
    unsigned m_rollCount; //滚动次数
    QButtonGroup *m_BtnGroup; //按钮盒子
    bool btnMoveEnable;

    QTimer *m_newT; //旋转定时器
};

#endif // PICTUREWIDGET_H

picturewidget.cpp:

#include "picturewidget.h"
#include "ui_picturewidget.h"
#include "pictureitem.h"
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QTimer>
#include <QPainterPath>
#include <QGraphicsView>
#include <QDebug>
#include <QQueue>
#include <QGraphicsItemAnimation>
#include <QTimeLine>
#include <cmath>
#include <ctime>
#include <QTransform>
#include <QButtonGroup>
#include <QMap>
static int dir = 0;//记录方向
static QList<qreal> spaceList;
static QList<qreal> unitList;
static QList<qreal> transScaleList;//缩放比例表
static QSize pictrueBigSize = RAW_VIEW_SIZE/SCALE_VIEW_PIXMAP;
static QSize pictrueSmallSize = RAW_VIEW_SIZE/SCALE_VIEW_PIXMAP/SCALE_BIG_SMALL;
static QList<pictureItem *> itemList;
static QList<int> finishList;
static QMap<int, pictureItem *> mapLink;  //按钮id 与 图片资源的映射
static int startNum = 0;
static QList<QPointF> pointA;

PictureWidget::PictureWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PictureWidget),
    m_timer(new QTimer(this)),
    m_scene(new QGraphicsScene(this)),
    m_index(0),
    m_currentRule(RuleA),
    m_rollCount(0),
    btnMoveEnable(true)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_StyledBackground); //设置样式表
    setButtonGroup(); //设置按钮组
    setInitList();
    setPictureScreen();
    setTimerAndConnect();

    m_newT = new QTimer(this);
    m_newT->setInterval(5000);
    connect(m_newT,&QTimer::timeout,[this](){
            on_btnR_clicked();
    });
    m_newT->start();
}

PictureWidget::~PictureWidget()
{
    m_newT->stop();
    delete ui;
}

void PictureWidget::setButtonGroup()
{
    m_BtnGroup = new QButtonGroup(this);
    m_BtnGroup->addButton(ui->btnPic0,0);
    m_BtnGroup->addButton(ui->btnPic1,1);
    m_BtnGroup->addButton(ui->btnPic2,2);
    m_BtnGroup->addButton(ui->btnPic3,3);
    m_BtnGroup->addButton(ui->btnPic4,4);
    m_BtnGroup->addButton(ui->btnPic5,5);
    m_BtnGroup->addButton(ui->btnPic6,6);
    m_BtnGroup->addButton(ui->btnPic7,7);
    m_BtnGroup->addButton(ui->btnPic8,8);
    m_BtnGroup->addButton(ui->btnPic9,9);
    m_BtnGroup->setExclusive(true);
    m_BtnGroup->button(1)->setChecked(true);
    for (int i = 0; i<10; i++) {
        static_cast<pictureButton*>(m_BtnGroup->button(i))->setId(i);
    }
}

void PictureWidget::setInitList()
{
    m_PointList << P1 << P2<< P3 << P4 << P5 << P6 << P7 << P8 << P9 << P10;
    m_ZValueList << 1 << 2 << 1  << 0  << 0  << 0  << 0  << 0  << 0  << 0;
    m_PixmapScaleList << 0.8<< 1 << 0.8 << 0.8 << 0.8 << 0.8 << 0.8 << 0.8 << 0.8 <<0.8;
}

void PictureWidget::setPictureScreen()
{
    //设置样式 无标边框
    ui->graphicsView->setStyleSheet("background: transparent; padding: 0px; border: 0px;");
    ui->graphicsView->setScene(m_scene);
    m_scene->setSceneRect(0,0,RAW_VIEW_SIZE.width(),RAW_VIEW_SIZE.height());

    m_MidLine.setPoints(QPointF(0,0),\
                      QPointF(RAW_VIEW_SIZE.width(),0));

    //添加对应图片
    for (int i = 1; i<=10;i++) {
        m_PixmapList.append(QPixmap(QString(":/images/picturewall/%1.png").arg(i)));
    }
    for (int i = 0; i<10;i++) {
        itemList.append(new pictureItem(m_PixmapList[i].scaled(pictrueBigSize,
                               Qt::KeepAspectRatio,Qt::SmoothTransformation)));
        itemList[i]->setScale(m_PixmapScaleList[i]);
        itemList[i]->setType(i);
        itemList[i]->setItemId(i);
        itemList[i]->setOffset(QPointF(0,0));
    }
    //图元添加图片
    for(int i = 0; i<10; i++)
    {
        m_scene->addItem(itemList[i]);//添加图元
        itemList[i]->setPos(m_MidLine.pointAt(m_PointList[i]));//设置位置
        itemList[i]->setZValue(m_ZValueList[i]);//设置显示优先级
        itemList[i]->setTransformationMode(Qt::SmoothTransformation);//设置缩放模式
        if(i != 1)
        {
           itemList[i]->setPos(itemList[i]->x(),RAW_VIEW_SIZE.height()/10);
        }
        pointA.append(itemList[i]->pos());  //放入到对应位置
        qDebug()<< pointA[i].x() << ": " << pointA[i].y();
    }
    //放入映射map中
    for(int i =0; i<10; i++)
    {
        mapLink.insert(static_cast<pictureButton*>(m_BtnGroup->button(i))->id(),itemList[i]);
    }

    QMap<int,pictureItem *>::const_iterator it;

    for (it = mapLink.constBegin();it!=mapLink.constEnd();it++) {
        qDebug()<< it.key()<< ": " << it.value();
    }

}

void PictureWidget::setTimerAndConnect()
{
    //利用持续时间和帧数计算出定时时间,持续时间/(帧数*持续时间),这里乘1000是转为秒
    m_timer->setInterval(DURATION_MS/(FPS*DURATION_MS/1000));
    connect(m_timer,&QTimer::timeout,this,&PictureWidget::timerOutFunc);

    for(int i = 0; i<10; i++)
    {
        connect(itemList[i],&pictureItem::clickedId,this,&PictureWidget::clickedItemRoll);
        void (pictureButton:: *funcPtr)(int) = &pictureButton::entered;
        connect(static_cast<pictureButton*>(m_BtnGroup->button(i)),funcPtr,[this](int id){
             pictureItem * p = mapLink.value(id); //获取id 的图片值
             btnMoveEnable = false;
             clickedItemRoll(p->type());
             qDebug()<<p->type();
        });
    }

}

int PictureWidget::getIndexByRules(int oldIndex, int rule)
{
    switch (rule) {
    case 1:
        return  (oldIndex+1)/10;
    case -1:
         return oldIndex==0?9:oldIndex-1;
    default:
        return 0;
    }

}

void PictureWidget::rollItem(int rollDir, unsigned rollCount)
{
    rollCount = 0;
    if(m_timer->isActive())
        return;
    //获取新的数据
    //主要位置  主位置
    int nbegin = rollDir;
    startNum = getrightN(nbegin);
    m_timer->start();
}

int PictureWidget::getrightN(int num)
{
    if(num == -1)
    {
        num = 9;
    }
    if(num == 10)
    {
        num = 0;
    }

    return num;
}

void PictureWidget::timerOutFunc()
{
//    on_btnR_clicked();

    QVector<QGraphicsItemAnimation *>item(10);

    for (int i = 0; i < 10; i++) {
        item[i] = new QGraphicsItemAnimation();
    }

    QTimeLine *timeline = new QTimeLine(200);
    timeline->setLoopCount(1); //设置3次
    int first = getrightN(startNum-1);
    for (int i = 0; i<10; i++) {
        itemList[i] = mapLink.value(first%10);
        first++;

//        QPointF point = m_MidLine.pointAt(m_PointList[i]);
//        itemList[i]->setPos(point);//设置位置
        itemList[i]->setScale(m_PixmapScaleList[i]);
        itemList[i]->setZValue(m_ZValueList[i]);//设置显示优先级
        itemList[i]->setTransformationMode(Qt::SmoothTransformation);//设置缩放模式
        item[i]->setItem(itemList[i]);
        item[i]->setTimeLine(timeline);
        item[i]->setPosAt(1,pointA[i]);

//        if(int(itemList[i]->zValue()) == 2)
//        {
//            item[i]->setScaleAt(1,1,1);
//        }

        itemList[i]->setPos(pointA[i]);

    }

//    QMap<int,pictureItem *>::const_iterator it;

//    for (it = mapLink.constBegin();it!=mapLink.constEnd();it++) {
//        qDebug()<< it.key()<< ": " << it.value();
//    }
    timeline->start();
    m_scene->invalidate();
    m_timer->stop();
}

void PictureWidget::clickedItemRoll(int type)
{
    if(m_timer->isActive())
        return;
    rollItem(type, 0); //得到最新的id 按钮位置
}

//左边运动
void PictureWidget::on_btnL_clicked()
{
    int id = m_BtnGroup->checkedId();
    if(id-1<0)
    {
        id = 9;
    }
    else {
        id = id -1;
    }
    m_BtnGroup->button(id)->setChecked(true);
    rollItem(id,0);
}
//右边运动
void PictureWidget::on_btnR_clicked()
{
    int id = m_BtnGroup->checkedId();
    id = (id+1)%10;
    m_BtnGroup->button(id)->setChecked(true);
    rollItem(id,0);
}

template<typename T>
void PictureWidget::rollList(QList<T> &oldList, int dir, int count)
{
    for(int i = 0; i<count; i++)
    {
        if(dir == 1)
        {
            oldList.prepend(oldList.last());
            oldList.removeLast();
        }
        else if(dir == -1)
        {
            oldList.append(oldList.first());
            oldList.removeFirst();
        }
    }

}

具体请看上方的链接博主。

主界面UI:

image-20230821221731955

目前项目工程如图:

image-20230821223430860

马上就要结束这个项目了,准备提取项目难点写到简历上了。

标签:Qt,PictureWidget,int,void,BtnGroup,ui,-----,include,轮播
From: https://www.cnblogs.com/dwinternet/p/17651785.html

相关文章

  • 2023年DAMA-CDGA/CDGP数据治理认证线上开班中,等你来
    DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义,帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力,促进开展工作实践应用及实际问题解决,形成企业所需的新数字经济下的核心职业竞争能力。DAMA是数据管理方面的认证,帮助数据从业者提升......
  • 2023年9月DAMA-CDGA/CDGP数据治理认证,进入报名
    据DAMA中国官方网站消息,2023年度第三期DAMA中国CDGA和CDGP认证考试定于2023年9月23日举行。 报名通道现已开启,相关事宜通知如下: 考试科目: 数据治理工程师(CertifiedDataGovernanceAssociate,CDGA)数据治理专家(CertifiedDataGovernanceProfessional,CDGP) 考试时间: CDGA:2023......
  • java-将列表格式化成json字符串
    List<String>list=newArrayList<>();list.add("{'county':'china','age':18}");list.add("{'county':'japan','age':28}");......
  • 如何在k8s中部署nfs-client-provisioner实现nfs共享存储的动态PV创建?
    0、背景说明 正常的情况,如果使用nfs的网络共享存储,需要手动的创建pv,然后创建pvc和pv进行绑定。 最后在应用程序的pod中来挂载使用这个pvc,达到挂载外部共享存储的目的。 那么,要实现动态的PV的创建,该怎么做呢? 在今天的内容里面,介绍一个nfs-client-provisoner工具,通过它......
  • [LeetCode][121]best-time-to-buy-and-sell-stock
    ContentYouaregivenanarraypriceswhereprices[i]isthepriceofagivenstockontheithday.Youwanttomaximizeyourprofitbychoosingasingledaytobuyonestockandchoosingadifferentdayinthefuturetosellthatstock.Returnthemaximu......
  • el-input-number 手动输入无法触发校验
    前情提要今天终于找到了鬼打墙之谁改了我的代码中的鬼,庆贺:-)鬼找到了:测试对象不一致请输入0-1000间的整数这则校验一直都有,不是改bug期间提交的,因此代码提交记录是正常的。 { pattern:/^([0-9][0-9]{0,2}|1000)$/, message:"请输入0-1000间的整数", tri......
  • 无法连接仓库:Command "git ls-remote -h -- https://gitee.com/xxx/xxxrned status co
    无法连接仓库:Command"gitls-remote-h--https://gitee.com/xxx/xxxrnedstatuscode128:stdout:stderr:remote:[session-554c92af]Usernamefor'https:Incorrectusernameorpassword(accesstoken)fatal:Authenticationfailedfor'http......
  • 【腾讯云 TDSQL-C Serverless 产品体验】 使用 Python 向 TDSQL-C 添加读取数据 实现
    前言TDSQL-CMySQL版(TDSQL-CforMySQL)是腾讯云自研的新一代云原生关系型数据库。融合了传统数据库、云计算与新硬件技术的优势,为用户提供具备高弹性、高性能、海量存储、安全可靠的数据库服务。TDSQL-CMySQL版100%兼容MySQL5.7、8.0。实现超百万级QPS的高吞吐,最高PB级智......
  • 文心一言 VS 讯飞星火 VS chatgpt (80)-- 算法导论7.4 5题
    五、如果用go语言,当输入数据已经“几乎有序”时,插入排序速度很快。在实际应用中,我们可以利用这一特点来提高快速排序的速度。当对一个长度小于k的子数组调用快速排序时,让它不做任何排序就返回。当上层的快速排序调用返回后,对整个数组运行插人排序来完成排序过程。试证明:这一排序......
  • low-ui-vue前置解读|实现一个动态列的表格组件
    最近另一个团队正式在项目中推广内部开发的low-ui组件库了,当然还在内部阶段,但是太慢了。作为架子的设计者和部分功能的开发者,我决定先把常见的功能通过模仿的形式公开出来。避免大家搜索无果或者使用一些框架增加学习成本。所谓动态列的表格,就是列数不固定。像广为使用的elementU......