QT触摸滑动效果,滚轮效果。

QT触摸滑动效果,滚轮效果。

先看效果,鼠标滑动,触摸滑动,鼠标滚轮都可以。自动更改月的日数。
主要分析的是滚动的效果,上层调用怎么用都可以。
在这里插入图片描述

1. 整体程序结构

  • 创建一个VerticalScroll的文件,形成一个类。这个类的父窗体必须是QWidget。
  • 使用MainWindow中的一个QWidget,显示VerticalScroll的类。可以创建多个窗口。
  • 类VerticalScroll,可以发送信号,也可以通过父窗体的程序改变各种设定。
    在这里插入图片描述

2. VerticalScroll的代码,有详细注解的

  • 使用方法:直接新建一个无界面文件,把 .h 和.cpp 复制进去就可以了。
  • 滚动效果需要几个关键的变量
    int Now_Value;//当前值
    int Min_Value;//最小值
    int Man_Value;//最大值
    bool isDragging;//鼠标按下标志位
    int Mouse_Press;//鼠标拖动值
    int Deviation;//显示偏移量
  • 先看 .h
#ifndef VERTICALSCROLL_H
#define VERTICALSCROLL_H

#include <QWidget>      //Widget头文件
#include <QPainter>     //画笔头文件
#include <QDebug>       //打印头文件
#include <QMouseEvent>  //鼠标头文件
#include <QWheelEvent>  //滚轮头文件

class VerticalScroll : public QWidget
{
    Q_OBJECT

public:
    explicit VerticalScroll(QWidget *parent = nullptr);//指定父窗体必须是 QWidget
    void SetRange(double min, double max);//设置范围
    int ReadValue();//获取当前值
    void SetValue(int value); //设定当前值

protected:
    void mousePressEvent(QMouseEvent *Mouse);   //按下
    void mouseMoveEvent(QMouseEvent *Mouse);    //移动
    void mouseReleaseEvent(QMouseEvent *);      //松开
    void wheelEvent(QWheelEvent *event);        //滚轮
    void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;             //画图程序
    void paintNum(QPainter &painter, double num, int deviation);//画图程序,调用的,写字程序

signals:
    void CurrentValueChanged(int value);

private:
    int Now_Value;//当前值
    int Min_Value;//最小值
    int Man_Value;//最大值
    bool isDragging;//鼠标按下标志位
    int Mouse_Press;//鼠标拖动值
    int Deviation;//显示偏移量
};

#endif // VERTICALSCROLL_H
  • 再看 .cpp
#include "verticalscroll.h"

VerticalScroll::VerticalScroll(QWidget *parent)
    : QWidget(parent),
      Now_Value(5),
      Min_Value(0),
      Man_Value(10),
      isDragging(false),
      Mouse_Press(0),
      Deviation(0)
{
    this->resize(150,230);//界面尺寸
}

void VerticalScroll::SetRange(double min, double max)//设置范围,父窗体调用
{
    Min_Value = min;
    Man_Value = max;

    if(Now_Value < Min_Value)
        Now_Value = Min_Value;
    if(Now_Value > Man_Value)
        Now_Value = Man_Value;

    Deviation = 0;
    update();
}

int VerticalScroll::ReadValue()//获取当前值,父窗体调用
{
    return Now_Value;
}

void VerticalScroll::SetValue(int value)//设定当前值,父窗体调用
{
    Now_Value = value;
    Deviation = 0;
    update();
}

void VerticalScroll::mousePressEvent(QMouseEvent *Mouse)//鼠标按下
{
    isDragging = true;//记录鼠标按下标志位
    Mouse_Press = Mouse->pos().y();//记录Y坐标,因为是上下滑动
}

void VerticalScroll::mouseMoveEvent(QMouseEvent *Mouse)//鼠标拖动
{
    if (isDragging)//鼠标按下,的移动,才算拖动
    {
        Deviation = Mouse->pos().y() - Mouse_Press;//获取便宜量

        int Height = height() - 1;//获取界面长

        if (Deviation > (Height) / 3)
        {
            Deviation = (Height) / 3;
        }
        if (Deviation < -(Height) / 3)
        {
            Deviation = -(Height) / 3;
        }
        update();//更新显示
    }
}

void VerticalScroll::mouseReleaseEvent(QMouseEvent *)//鼠标放开,弹回最近的数字
{
    if (isDragging)
        isDragging = false;

    int Height = height() - 1;//获取界面长

    if((Deviation > (Height/3)/2) && (Now_Value > Min_Value))
    {
        Now_Value -= 1;
    }
    if((Deviation < (-Height/3)/2) && (Now_Value < Man_Value))
    {
        Now_Value += 1;
    }
    Deviation = 0;//偏移归零
    update();//更新显示
}

void VerticalScroll::wheelEvent(QWheelEvent *event)//滚轮
{
    if(event->delta() > 0)//向上滚轮
    {
        if(Now_Value > Min_Value)
            Now_Value -= 1;
    }
    else//向下滚轮
    {
        if(Now_Value < Man_Value)
            Now_Value += 1;
    }
    Deviation = 0;
    update();//更新显示
}

void VerticalScroll::paintEvent(QPaintEvent *)//绘制事件,调用update时更新显示
{
    static int Old_Now_Value = 0;
    QPainter painter(this);//创建画板

    int Width = width() - 1;//获取长和宽
    int Height = height() - 1;

    painter.setRenderHints(QPainter::Antialiasing,true);//创建画板
    painter.save();//保存当前绘制器状态
    painter.setBrush(QColor(200,200,200));//画板颜色
    painter.drawRect(0,0,width(),height());//画板尺寸
    painter.restore();//恢复当前的绘制状态

    //如果偏移了过大
    if((Deviation >= Height/3) && (Now_Value > Min_Value))
    {
        Mouse_Press += Height/3;//偏移初值
        Deviation -= Height/3;
        Now_Value -= 1;
    }
    if((Deviation <= -Height/3) && (Now_Value < Man_Value))
    {
        Mouse_Press -= Height/3;//偏移初值
        Deviation += Height/3;
        Now_Value += 1;
    }

    paintNum(painter,Now_Value,Deviation);//显示当前值
    if(Old_Now_Value != Now_Value)
    {
        Old_Now_Value = Now_Value;
        emit CurrentValueChanged(Now_Value);
    }

    if(Now_Value > Min_Value)
        paintNum(painter,Now_Value-1,Deviation-Height/3);//显示上一个值

    if(Now_Value < Man_Value)
        paintNum(painter,Now_Value+1,Deviation+Height/3);//显示下一个值
        
    //补空位的一个显示,让过度平滑
    if(Deviation > 0)//>0是-1,<0是+1
    {
        if(Now_Value > Min_Value+1)//显示-2的数字
            paintNum(painter,Now_Value-2,-Height/3*2+Deviation);
    }
    else
    {
        if(Now_Value < Man_Value+1)//显示+2的数字
            paintNum(painter,Now_Value+2,+Height/3*2+Deviation);
    }
    
    //画两个横杠,画面效果
    QPen pen;//创建画笔
    pen.setColor(QColor(40,40,40));//颜色
    pen.setWidth(Height/40);//线宽
    painter.setPen(pen);//拿起画笔
    painter.drawLine(QPoint(15,Height/3),QPoint(Width-15,Height/3));//画两条线
    painter.drawLine(QPoint(15,(Height/3)*2),QPoint(Width-15,(Height/3)*2));//画两条线
}

void VerticalScroll::paintNum(QPainter &painter, double num, int deviation)//画笔的指针,显示的数字,偏移量(+向下-向上)
{
    int Width = width() - 1;//获取长和宽
    int Height = height() - 1;
    int size = (Height - qAbs(deviation)) / 12; //偏移量越大,数字越小
    int transparency = 255 - 255 * qAbs(deviation) / Height;//偏移量越大,透明度越高
    int height = Height / 3;
    int y = Height / 2 + deviation - height / 2;
    painter.setPen(QColor(0,0,0,transparency));//设置颜色和透明度
    painter.setFont(QFont(painter.font().family(),static_cast<int>(size*1.5),750));//设置字体大小
    painter.drawText(QRectF(0, y, Width, height),Qt::AlignCenter,QString::number(num)+"");//写字
}
  • 简单说明一下,其实程序里都有注解。
    主要功能是使用paintEvent绘制事件,调用update时更新显示
    变量Deviation是偏移量,偏移量越大,字体越小,颜色越淡,就是效果
    鼠标按下时候,记录一个Y值,移动改变Y值,随之改变偏移量。
    鼠标放开时候,根据偏移量的大小,回弹的最近的数字上。

3.父窗体的调用

  • 第一步:在 .h 里创建类指针。
    VerticalScroll *My1_VerticalScroll;//创建类
    VerticalScroll *My2_VerticalScroll;//创建类
    VerticalScroll *My3_VerticalScroll;//创建类
  • 显示窗口,调用函数
    My1_VerticalScroll = new VerticalScroll(ui->widget);//new出一个VerticalScroll窗口
    My1_VerticalScroll->move(0,0);//设置窗口位置
    My1_VerticalScroll->SetRange(2010,2030);//设定最大最小值
    My1_VerticalScroll->SetValue(2021);//设定当前值
  • 连接槽
    connect(My1_VerticalScroll,&VerticalScroll::CurrentValueChanged,[=](int value)
    {
        value = value;
        int Days,Month,Year,NowDay;
        Year =  My1_VerticalScroll->ReadValue();//获取年
        Month = My2_VerticalScroll->ReadValue();//获取月
        NowDay= My3_VerticalScroll->ReadValue();//获取日
        Days =  GetDaysOfMonth(Year,Month);//获取天数
        My3_VerticalScroll->SetRange(1,Days);//设定天数
        DateTime.setDate(QDate(Year,Month,NowDay));//更新日期
        qDebug()<<DateTime;
    });

4.可以扩展的地方

  • 这个程序是垂直滑动的,可以按这个思路改成水平滑动的
  • 滚动的数字是int型,如果需要小数点,可以改成double,上下加减的数值也可以用变量。
  • 界面尺寸大小,现在是固定的,可以安要求改变。
  • 后续把工程源码上传,敬请期待!
  • 工程链接
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值