在不使用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;
}
可实现水平滑动与垂直滑动,可自由选择水平布局、垂直布局、网格布局;
实现效果如下: