QT_嵌入式主界面添加与切换效果

一、演示效果

在这里插入图片描述

二、源码

滑动页.c文件

#include "sliderwidget.h"

#include <QScroller>
#include <QScrollerProperties>
#include <QScrollBar>
#include <QCursor>
#include <QLabel>
#include <QPixmap>

SliderWidget::SliderWidget(QWidget *parent)
    : QWidget(parent)
{
    initUi();
    initCtrl();
}

SliderWidget::~SliderWidget()
{
}

void SliderWidget::initUi()
{
    m_pMainWidget = new QWidget(this);
    m_pMainWidget->setStyleSheet("background: transparent;");

    //滚动视图模拟切换界面
    m_pScrollArea = new QScrollArea(this); //QScrollArea 类提供到另一个小部件的滚动视图。
    m_pScrollArea->setAlignment(Qt::AlignCenter);//用函数setAlignment(),可以将这几个QLabel无缝拼接起来
    m_pScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_pScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_pScrollArea->setWidget(m_pMainWidget);
    m_pScrollArea->setWidgetResizable(true);
    m_pScrollArea->setStyleSheet("background: transparent;"
                                 "border: 1px solid transparent;");

    auto scroller = QScroller::scroller(m_pScrollArea);
    scroller->grabGesture(m_pScrollArea, QScroller::LeftMouseButtonGesture);

    auto properties = scroller->scrollerProperties();
    properties.setScrollMetric(QScrollerProperties::SnapTime, 0.8);
    properties.setScrollMetric(QScrollerProperties::MinimumVelocity, 1);
    scroller->setScrollerProperties(properties);

    //main窗口的设计
    m_pMainLayout = new QHBoxLayout;
    m_pMainLayout->setMargin(0);
    m_pMainLayout->setSpacing(0);
    m_pMainWidget->setLayout(m_pMainLayout);


    //下标滑动块的设计
    m_pIndicatorWidget = new QWidget(this);
    m_pIndicatorLayout = new QHBoxLayout;
    m_pIndicatorLayout->setAlignment(Qt::AlignCenter);
    m_pIndicatorLayout->setMargin(0); //表示控件与窗体的左右边距
    m_pIndicatorLayout->setSpacing(0);
    m_pIndicatorWidget->setLayout(m_pIndicatorLayout);
}

void SliderWidget::initCtrl()
{
    m_pAnimation = new QPropertyAnimation(m_pScrollArea->horizontalScrollBar(), "value", this);
    m_pAnimation->setDuration(200);
    m_pAnimation->setEasingCurve(QEasingCurve::OutCurve);

    m_pSlidingTimer = new QTimer(this);
    m_pSlidingTimer->setInterval(300);

    connect(QScroller::scroller(m_pScrollArea), &QScroller::stateChanged, this, &SliderWidget::onScrollerStateChanged);
    connect(m_pSlidingTimer, &QTimer::timeout, this, &SliderWidget::onSliderTimerTimeout);
}

void SliderWidget::updateIndicator(int index)
{
    const QObjectList &childs = m_pIndicatorWidget->children();
    for (int i=1; i<childs.count(); ++i)
    {
        auto pIndicatorLbl = qobject_cast<QLabel*>(childs[i]);

        if (i-1 == index)
            pIndicatorLbl->setPixmap(QPixmap(":/misc/sliderwidget/image/indicatoractive.png"));
        else
             pIndicatorLbl->setPixmap(QPixmap(":/misc/sliderwidget/image/indicatorinactive.png"));
   }
}

int SliderWidget::addWidget(QWidget *page)
{
    m_pMainLayout->addWidget(page);

    auto pIndicatorLbl = new QLabel;
    m_pIndicatorLayout->addWidget(pIndicatorLbl);

    if (count() == 1)
        pIndicatorLbl->setPixmap(QPixmap(":/misc/sliderwidget/image/indicatoractive.png"));
    else
       pIndicatorLbl->setPixmap(QPixmap(":/misc/sliderwidget/image/indicatorinactive.png"));

    return count() - 1;
}

int SliderWidget::count() const
{
    return m_pMainLayout->count();
}

int SliderWidget::currentIndex() const
{
    return m_curPageIndex;
}

QWidget *SliderWidget::currentWidget() const
{
    if (count() == 0)
        return nullptr;

    return qobject_cast<QWidget*>(m_pMainWidget->children()[m_curPageIndex+1]);
}

int SliderWidget::indexOf(QWidget *widget) const
{
    auto index = m_pMainWidget->children().indexOf(widget);

    return index == -1 ? -1 : index -1;
}

void SliderWidget::setCurrentIndex(int index)
{
    if (index < 0 || index >= count())
        return;

    m_pAnimation->setStartValue(m_pScrollArea->horizontalScrollBar()->value());
    m_pAnimation->setEndValue(index * this->width());
    m_pAnimation->start();

    m_curPageIndex = index;
    updateIndicator(m_curPageIndex);
    emit currentChanged(m_curPageIndex);
}

void SliderWidget::setCurrentWidget(QWidget *widget)
{
    auto index = m_pMainWidget->children().indexOf(widget);

    if (index == -1)
        return;

    setCurrentIndex(index - 1);
}

void SliderWidget::removeWidget(int index)
{
    if (index < 0 || index >= count() || count() <= 1)
        return;

    auto widget = qobject_cast<QWidget*>(m_pMainWidget->children()[index+1]);
    auto indicator = qobject_cast<QWidget*>(m_pIndicatorWidget->children()[index+1]);

    m_pMainLayout->removeWidget(widget);
    m_pIndicatorLayout->removeWidget(indicator);

    delete widget;
    delete indicator;

    setCurrentIndex(0);
}

void SliderWidget::removeWidget(QWidget *widget)
{
    removeWidget(indexOf(widget));
}

void SliderWidget::resizeEvent(QResizeEvent *ev)
{
    Q_UNUSED(ev)

    m_pScrollArea->resize(this->size());
    m_pMainWidget->resize(this->width() * m_pMainLayout->count(), this->height() - 2);
    m_pIndicatorWidget->setGeometry(0, this->height() - 20, this->width(), 20);

    QWidget::resizeEvent(ev);
}

void SliderWidget::onScrollerStateChanged(QScroller::State state)
{
    if (count() == 0)
        return;

    if (state == QScroller::State::Inactive)
    {
        m_pSlidingTimer->stop();
        m_sliderReleaseValue = QCursor::pos().x();
        if (m_sliderReleaseValue == m_sliderPressedValue)
            return;

        if (!m_sliderFlag)
        {
            if (m_sliderPressedValue - m_sliderReleaseValue > 20)
                ++m_nextPageIndex;
            else if (m_sliderReleaseValue - m_sliderPressedValue > 20)
                --m_nextPageIndex;

            if (m_nextPageIndex > count())
                m_nextPageIndex = count() - 1;
            else if (m_nextPageIndex < 0)
                m_nextPageIndex = 0;
        }
        else
        {
            int value = m_pScrollArea->horizontalScrollBar()->value();
            m_nextPageIndex = (value / this->width()) + (value % this->width() / (this->width() / 2));
        }

        if (m_nextPageIndex != m_curPageIndex)
        {
            m_curPageIndex = m_nextPageIndex;
            updateIndicator(m_curPageIndex);
            emit currentChanged(m_curPageIndex);
        }

        m_pAnimation->setStartValue(m_pScrollArea->horizontalScrollBar()->value());
        m_pAnimation->setEndValue(m_nextPageIndex * this->width());
        m_pAnimation->start();

        m_sliderReleaseValue = 0;
        m_sliderPressedValue = 0;
        m_sliderFlag = 0;
    }

    if (state == QScroller::State::Pressed)
    {
        m_nextPageIndex = m_curPageIndex = m_pScrollArea->horizontalScrollBar()->value() / this->width();
        m_sliderPressedValue = QCursor::pos().x();
        m_pSlidingTimer->start();
    }
}

void SliderWidget::onSliderTimerTimeout()
{
    m_pSlidingTimer->stop();
    m_sliderFlag = true;
}

滑动页.h文件

#ifndef SLIDERWIDGET_H
#define SLIDERWIDGET_H

#include <QHBoxLayout>
#include <QPropertyAnimation>
#include <QScrollArea>
#include <QScroller>
#include <QTimer>
#include <QWidget>

class SliderWidget : public QWidget
{
    Q_OBJECT

public:
    SliderWidget(QWidget *parent = nullptr);
    ~SliderWidget();

    int addWidget(QWidget *page);
    int count() const;
    int currentIndex() const;
    QWidget *currentWidget() const;
    int indexOf(QWidget *widget) const;

public slots:
    void setCurrentIndex(int index);
    void setCurrentWidget(QWidget *widget);

    void removeWidget(int index);
    void removeWidget(QWidget *widget);

protected:
    void resizeEvent(QResizeEvent *ev) override;

protected slots:
    void onScrollerStateChanged(QScroller::State state);
    void onSliderTimerTimeout();

signals:
    void currentChanged(int index);

private:
    void initUi();
    void initCtrl();
    void updateIndicator(int index);

private:
    QWidget *m_pMainWidget;
    QScrollArea *m_pScrollArea;
    QHBoxLayout *m_pMainLayout;
    QWidget *m_pIndicatorWidget;

    QHBoxLayout *m_pIndicatorLayout; //下标滑动界面的标点

    QPropertyAnimation *m_pAnimation;
    QTimer *m_pSlidingTimer;

    bool m_sliderFlag = false;
    int m_sliderPressedValue = 0;
    int m_sliderReleaseValue = 0;
    int m_curPageIndex = -1;
    int m_nextPageIndex = -1;
};

#endif // SLIDERWIDGET_H

三、完整工程

qq:1528751813或者评论区留下邮箱!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值