QRubberBand橡皮筋+自定义样式
一、介绍
1、QRubberBand名为橡皮筋选中:选中一个东西,显示其边框。一般是结合鼠标事件同时完成某项需求。单独没什么意义。
二、代码案例
在一个空白窗口内,展示多个复选框控件,通过橡皮筋实现批量选中与取消选中效果。
当鼠标按下,需要创建一个橡皮筋控件,鼠标移动的时候,调整橡皮筋控件的范围区域,当松开鼠标,拿到橡皮筋选中区域做判定,那些子控件在选中区域范围内,改变他的选中标识。
创建一个QtRubberBand项目,并使用QMainWindow作为主窗口,并放置一些复选框(注意不要添加布局)。
具体代码如下:
MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QDebug> //添加调试日志头文件
#include <QMouseEvent>
#include <QRubberBand>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建橡皮筋控件,并设置为矩形
m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
/******* 鼠标左键按下时,设置为开始框选,显示橡皮筋 ********/
//记录鼠标按下开始位置
m_startPos = event->pos();
//鼠标刚按下去是没有尺寸的,所以给他一个空的尺寸
m_rubberBand->setGeometry(QRect(m_startPos, QSize()));
//显示橡皮筋控件
m_rubberBand->show();
}
QMainWindow::mousePressEvent(event); //事件继续向下传递
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
/******* 鼠标移动时,更新橡皮筋的尺寸,并根据框选范围勾选复选框控件 ********/
if (m_rubberBand->isVisible()) {
//橡皮筋控件是显示的,则更新橡皮筋的尺寸
m_rubberBand->setGeometry(QRect(m_startPos, event->pos()).normalized());
}
QMainWindow::mouseMoveEvent(event); //事件继续向下传递
}
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
/******* 鼠标松开时,隐藏橡皮筋,并根据框选范围勾选复选框控件 ********/
if (m_rubberBand->isVisible()) {
//获取橡皮筋控件的尺寸范围
const QRect rect = m_rubberBand->geometry();
//查找所有复选框控件
QList<QCheckBox*> checkBoxs = this->findChildren<QCheckBox*>();
for (auto checkBox : checkBoxs) {
//判断框选尺寸范围,是否包含复选框控件尺寸范围
if(rect.contains(checkBox->geometry())) {
//切换勾选状态
checkBox->toggle();
}
}
//隐藏橡皮筋的尺寸
m_rubberBand->hide();
}
QMainWindow::mouseReleaseEvent(event);
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class QRubberBand;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
//重写鼠标按下事件
void mousePressEvent(QMouseEvent * event) override;
//重写鼠标移动事件
void mouseMoveEvent(QMouseEvent* event) override;
//重写鼠标松开事件
void mouseReleaseEvent(QMouseEvent * event) override;
private:
Ui::MainWindow *ui;
QPoint m_startPos; //鼠标按下开始位置
QRubberBand *m_rubberBand = nullptr; //橡皮筋
};
#endif // MAINWINDOW_H
运行效果图:
框选
框选完成
三、自定义样式
有时候,我们需要已定义橡皮筋的样式,此时我们就需要重写QRubberBand,重新实现重绘函数即可。
下面是将橡皮筋修改成深蓝色线框,框选背景为透明的代码:
MyRubberBand.cpp
#include "MyRubberBand.h"
#include "qevent.h"
#include <QPainter>
MyRubberBand::MyRubberBand(Shape shape, QWidget *parent)
: QRubberBand(shape, parent)
{
}
void MyRubberBand::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//设置画笔为深蓝色,画笔宽度为4
painter.setPen(QPen(QColor(0, 100, 179), 4));
//设置背景色为透明
painter.setBrush(Qt::transparent);
//绘制框选的矩形图形
painter.drawRect(event->rect());
}
MyRubberBand.h
#ifndef MYRUBBERBAND_H
#define MYRUBBERBAND_H
#include <QRubberBand>
//继承QRubberBand,进行扩展重写
class MyRubberBand : public QRubberBand
{
Q_OBJECT
public:
explicit MyRubberBand(Shape shape, QWidget *parent = nullptr);
protected:
//重写绘制事件
void paintEvent(QPaintEvent *event) override;
};
#endif // QRUBBERBAND_H
我们在new的时候使用我们的MyRubberBand类创建接口,如下
#include "MyRubberBand.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建橡皮筋控件,并设置为矩形
//m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
m_rubberBand = new MyRubberBand(QRubberBand::Rectangle, this);
}
效果图如下: