Qt模仿Android、IOS滑动窗口效果

 

一、期望的效果:

 
 

二、模仿实现的效果

 
 

三、源码

3.1 widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QScrollBar>
#include <QPropertyAnimation>
#include <QDateTime>
#include <QTimer>
#include <QDebug>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;

    QScrollBar *m_scrollBarV;

protected:
    bool eventFilter(QObject *obj, QEvent *event);
};

#endif // WIDGET_H

 
 

3.2 widget.cpp

 

 
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    m_scrollBarV = ui->tableWidget->verticalScrollBar();
    QObjectList objectList = ui->tableWidget->children();
    for(int i = 0; i < objectList.count(); i++)
    {
        if(objectList.at(i)->objectName() == "qt_scrollarea_viewport")
        {
            objectList.at(i)->installEventFilter(this);
        }
    }
}

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

bool Widget::eventFilter(QObject *obj, QEvent *event)
{
    static int press_y   = 0;
    static int move_y    = -1;
    static int release_y = 0;
    static QDateTime pressDateTime;
    static QPropertyAnimation *animation = new QPropertyAnimation();

    if("qt_scrollarea_viewport" != obj->objectName())
    {
        return false;
    }

    int scrollV_max = m_scrollBarV->maximum ();
    int scrollV_min = m_scrollBarV->minimum ();

    //根据鼠标的动作——按下、放开、拖动,执行相应的操作
    if(event->type() == QEvent::MouseButtonPress)
    {
        //记录按下的时间、坐标

        pressDateTime = QDateTime::currentDateTime();
        move_y  = QCursor::pos().y();
        press_y = move_y;

        animation->stop();
    }
    else if(event->type() == QEvent::MouseButtonRelease)
    {
        //鼠标放开,根据鼠标拖动的垂直距离和持续时间,设置窗口滚动快慢程度和距离

        if(animation->targetObject() != m_scrollBarV)
        {
            animation->setTargetObject(m_scrollBarV);
            animation->setPropertyName("value");
        }

        move_y = -1;
        release_y = QCursor::pos().y();
//        qDebug()<<"MouseButtonRelease QCursor::pos().y()="<<QCursor::pos().y();
        QObject *parent_obj = obj->parent();
        if(parent_obj != 0 || parent_obj->inherits("QAbstractItemView"))
        {
            QTimer::singleShot(150, (QAbstractItemView *)parent_obj
                               , SLOT(clearSelection()));
        }

        int endValue;
        int pageStep;
        if(release_y - press_y != 0 && qAbs(release_y - press_y) > 45)
        {
            //qDebug()<<"obj->objectName()="<<obj->objectName();
            int mseconds = pressDateTime.msecsTo(QDateTime::currentDateTime());
//            qDebug()<<"mseconds="<<mseconds;

            int limit = 440;
            pageStep = 240;//scrollBarV->pageStep();
//            qDebug()<<"pageStep="<<pageStep;
            if(mseconds > limit)//滑动的时间大于某个值的时候,不再滚动(通过增加分母)
            {
                mseconds = mseconds + (mseconds - limit) * 20;
            }

            if(release_y - press_y > 0)
            {
                endValue = m_scrollBarV->value()
                        - pageStep * (200.0 / mseconds);//.0避免避免强制转换为整形
                if(scrollV_min > endValue)
                {
                    endValue = scrollV_min;
                }
            }
            else if(release_y - press_y < 0)
            {
                    endValue = m_scrollBarV->value() + pageStep * (200.0 / mseconds);
                    if(endValue > scrollV_max)
                    {
                        endValue = scrollV_max;
                    }
            }
            if(mseconds > limit)
            {
                mseconds = 0;//滑动的时间大于某个值的时候,滚动距离变小,减小滑动的时间
            }
            animation->setDuration(mseconds+550);
            animation->setEndValue(endValue);
            animation->setEasingCurve(QEasingCurve::OutQuad);
            animation->start();
            return true;
        }
    }
    else if(event->type() == QEvent::MouseMove && move_y >= 0)
    {
        //窗口跟着鼠标移动

        int move_distance = QCursor::pos().y() - move_y;
        int endValue = m_scrollBarV->value() - move_distance;
        if(scrollV_min > endValue)
        {
            endValue = scrollV_min;
        }

        if(endValue > scrollV_max)
        {
            endValue = scrollV_max;
        }
        m_scrollBarV->setValue(endValue);
        //qDebug()<<"endValue="<<endValue;
        //qDebug()<<"move_distance="<<move_distance;
        move_y = QCursor::pos().y();
    }
    return false;
}

 
 

四、源码下载链接

 

五、应用场景

嵌入式设备
 
 

六、本人开发环境

win7 + Qt Creator 5.5.0
 
 
 
  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Qt框架下模仿iOS语音波形图,可以使用Qt Multimedia模块和Qt Quick绘图功能来实现。 首先,我们需要使用Qt Multimedia模块录制音频,并获取音频的波形数据。通过QAudioInput类可以实现音频录制,并使用QAudioFormat设置音频格式。在录制过程中,可以通过QBuffer类收集音频数据,并使用QAudioBuffer将音频数据转换为波形数据。 接下来,我们可以将获取的波形数据显示在Qt Quick界面上的图形组件中。可以创建一个自定义的波形图形组件,继承自QQuickPaintedItem,并实现paint方法来绘制波形图形。在paint方法中,根据波形数据使用QPainter进行绘制,并根据音频的时间轴来确定波形的位置和形状。可以使用不同的颜色和样式来显示波形,以逼真地模仿iOS的语音波形图。 除了绘制波形图形,我们还可以为波形图形组件添加一些交互功能,例如拖动、缩放等。可以通过重写鼠标事件和触摸事件来实现这些功能,例如根据鼠标或手指的位置来确定当前选择的波形片段,并提供相应的操作。 最后,我们将自定义的波形图形组件嵌入到Qt Quick的界面中,通过QML语言进行布局和样式的调整。可以根据需要添加其他的界面元素,例如播放按钮、录制按钮等。 通过以上步骤,我们可以在Qt实现一个模仿iOS语音波形图的界面。这样可以让用户在Qt应用程序中更加直观和便捷地查看和编辑音频波形数据。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值