qt 实现无滚动条的滑动效果

 在不使用qml的情况下,仅使用qt实现手指可左右滑动显示出内容。

直接上代码。

 qScrollAreaClass.h

#ifndef QSCROLLAREACLASS_H
#define QSCROLLAREACLASS_H

#include <QObject>
#include <QScrollArea>
#include <QMouseEvent>
#include <QWidget>

class QSCROLLAREACLASS : public QWidget
{
    Q_OBJECT
public:
    explicit QSCROLLAREACLASS(QWidget *parent = nullptr);

protected:
    bool eventFilter(QObject *watched, QEvent *event)   override;
    void mousePressEvent(QMouseEvent*)                  override;
    void mouseReleaseEvent(QMouseEvent*)                override;
    void mouseMoveEvent(QMouseEvent*)                   override;

private:
    bool            bPressed;
    QPoint          qPointPress;
    QScrollArea    *qScrollArea;

public:

signals:
    void signalBtnClicked(int iBtnIndex);

public slots:
    void slotBtnClicked(int iBtnIndex);

};

#endif // QSCROLLAREACLASS_H

 qScrollAreaClass.cpp

#include "qScrollAreaClass.h"           // QSCROLLAREACLASS qScrollAreaClass;

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QScrollArea>
#include <QScrollBar>
#include <QDebug>

/*****************************************************************
* 类名称: #include "qScrollAreaClass.h"           // QSCROLLAREACLASS qScrollAreaClass;
* 类描述: 创建不包含滚动条的区域,添加多个按钮 并且可左右滑动
* 作者:   XLY
* 时间:   2023-05-22
******************************************************************/
QSCROLLAREACLASS::QSCROLLAREACLASS(QWidget *parent)
    : QWidget(parent)
{
    this->qScrollArea = new QScrollArea(this);
    this->qScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);    // 隐藏水平滚动条
    this->qScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);      // 隐藏垂直滚动条

    // 创建滚动区域的内容
    QWidget         *qWidgetScrollContent   = new QWidget();
    //QHBoxLayout     *qHBoxLayout            = new QHBoxLayout(qWidgetScrollContent);        // 水平布局
    //QVBoxLayout     *qVBoxLayout            = new QVBoxLayout(qWidgetScrollContent);    // 垂直布局
    QGridLayout     *qGridLayout            = new QGridLayout(qWidgetScrollContent);    // 网格布局


    // 添加10个按钮
    for (int i = 0; i < 10; ++i)
    {
        QPushButton *qBtn = new QPushButton(QString("Button %1").arg(i + 1));
        qBtn->setFixedSize(150, 50);                // 设置每个按钮的宽与高
        //qHBoxLayout->addWidget(qBtn);               // 水平
        //qVBoxLayout->addWidget(qBtn);               // 垂直
        qGridLayout->setRowStretch(4,150);          // 网格布局行数 按钮宽
        qGridLayout->setColumnStretch(3,50);        // 网格布局列数 按钮高
        qGridLayout->addWidget(qBtn);               // 网格布局
        qBtn->installEventFilter(this);             // 添加事件过滤
        qBtn->setProperty("buttonIndex", i);        // 每个按钮设置属性值
    }
    // 设置滚动区域的内容
    this->qScrollArea->setWidget(qWidgetScrollContent);
    // 设置滚动区域的大小,使其只显示5个按钮
    //this->qScrollArea->setFixedSize(5 * 100,    70);   // 水平 设置滚动区域可显示的宽与高
    //this->qScrollArea->setFixedSize(170,        5*70);   // 垂直 设置滚动区域可显示的宽与高
    this->qScrollArea->setFixedSize(400,        300);   // 垂直 设置滚动区域可显示的宽与高
    // 所有按钮点击事件
    connect(this, SIGNAL(signalBtnClicked(int)), this, SLOT(slotBtnClicked(int)));
}

void QSCROLLAREACLASS::mousePressEvent(QMouseEvent *event)
{
    // Q_UNUSED(event)
    if(event->button() == Qt::LeftButton)
    {
        this->bPressed      = true;
        this->qPointPress   = QCursor::pos();
    }
    else if(event->button() == Qt::RightButton)
    {
        ;
    }
}

void QSCROLLAREACLASS::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event)
    this->bPressed      = false;
    this->qPointPress.setX(0);
    this->qPointPress.setY(0);
}

void QSCROLLAREACLASS::mouseMoveEvent(QMouseEvent *event)
{
    Q_UNUSED(event)
    if(this->bPressed)
    {
        QPoint qPointNewPos = QCursor::pos();
        float xDis = qPointNewPos.x() - this->qPointPress.x();				// 水平 计算移动后和按下时的坐标差x
        float yDis = qPointNewPos.y() - this->qPointPress.y();				// 垂直 计算移动后和按下时的坐标差y
        this->qScrollArea->horizontalScrollBar()->setValue(this->qScrollArea->horizontalScrollBar()->value() - xDis);   // 水平
        //this->qScrollArea->verticalScrollBar()->setValue(this->qScrollArea->verticalScrollBar()->value() - yDis);       // 垂直
        qPointPress = QCursor::pos();
    }
}

void QSCROLLAREACLASS::slotBtnClicked(int iBtnIndex)
{
    qDebug() << "Button" << iBtnIndex + 1 << "clicked";
}

bool QSCROLLAREACLASS::eventFilter(QObject *watched, QEvent *event)     // watched 对象 event 事件
{
    if(event->type()==QEvent::MouseButtonPress)             // 按下按钮执行
    {
        //qDebug()<<"btn press";
        QMouseEvent* mouseEvent =static_cast<QMouseEvent*>(event);
        Q_UNUSED(mouseEvent);
        this->bPressed      = true;
        this->qPointPress   = QCursor::pos();
    }
    else if(event->type()==QEvent::MouseMove)               // 按钮移动执行
    {
        //qDebug()<<"btn move";
        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
        Q_UNUSED(mouseEvent);
        if(this->bPressed && (!(this->qPointPress.isNull())))
        {
            QPoint qPointNewPos = QCursor::pos();
            float xDis = qPointNewPos.x() - this->qPointPress.x();				// 水平 计算移动后和按下时的坐标差x
            float yDis = qPointNewPos.y() - this->qPointPress.y();				// 垂直 计算移动后和按下时的坐标差y
            this->qScrollArea->horizontalScrollBar()->setValue(this->qScrollArea->horizontalScrollBar()->value() - xDis);   // 水平
            //this->qScrollArea->verticalScrollBar()->setValue(this->qScrollArea->verticalScrollBar()->value() - yDis);       // 垂直
            qPointPress = QCursor::pos();
        }

    }
    else if(event->type()==QEvent::MouseButtonRelease)      // 按钮释放执行
    {
        //qDebug()<<"btn release";
        this->bPressed      = false;
        this->qPointPress.setX(0);
        this->qPointPress.setY(0);

        QPushButton *qBtn = qobject_cast<QPushButton *>(watched);
        if (qBtn)
        {
            int iBtnIndex = qBtn->property("buttonIndex").toInt();
            emit signalBtnClicked(iBtnIndex);
            return true;
        }
    }
    else
    {
        ;
    }
    return QWidget::eventFilter(watched,event);
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "qScrollAreaClass.h"           // QSCROLLAREACLASS qScrollAreaClass;

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

public:
    QSCROLLAREACLASS    *qScrollAreaClass;

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    qScrollAreaClass = new QSCROLLAREACLASS(this);

}

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

可实现水平滑动与垂直滑动,可自由选择水平布局、垂直布局、网格布局;

实现效果如下:

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值