QScroller
Qt QTableWidget 触摸屏上滑动效果
代码
// 创建 QScroller 对象并与 tableWidget 关联.QScroller *pScroller = QScroller::scroller(ui->tableView);// 捕获滚动手势.pScroller->grabGesture(ui->tableView, QScroller::LeftMouseButtonGesture);// 设置垂直滚动模式为逐像素滚动.ui->tableView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
不足
自带的滚动条失效
:右侧拖动滚动条滑动,反而触发了触摸滑动操作
还未解决
自定义 CustomScroll
源自:Qt利用tablewidget模拟手指实现滑动
效果
代码
CustomScrollWidget.h
#ifndef CUSTOMSCROLLWIDGET_H
#define CUSTOMSCROLLWIDGET_H#include <QObject>
#include <QWidget>
#include <QTimer>
#include <QTableView>
#include <QPropertyAnimation>
#include <QDateTime>
class CustomScroll : public QWidget
{Q_OBJECTtypedef enum tagLuiScrollMouseDragInfo {MOUSE_RELEASE = 0, //鼠标离开MOUSE_PRESS = 1, //按下MOUSE_PRESS_MOVE = 2, //按下移动MOUSE_RELEASE_MOVE = 3 //鼠标离开并滑动}LUI_Scroll_Mouse_Drag_INFO_E;LUI_Scroll_Mouse_Drag_INFO_E m_dragFlag = MOUSE_RELEASE;QTimer m_scrollTimer;QTimer m_selectTimer;QTableView *m_table;QScrollBar *m_scrollBar;QPropertyAnimation *animation;int m_selectRow;int m_srcollH;void paintEvent(QPaintEvent *);bool eventFilter(QObject *obj, QEvent *evt);public:explicit CustomScroll(QTableView* table,QWidget *parent = nullptr);signals:public slots:void scrollTimeOut();void selectTimeOut();
};#endif // CUSTOMSCROLLWIDGET_H
CustomScrollWidget.cpp
#include "CustomScrollWidget.h"
#include <QMouseEvent>
#include <QDebug>
#include <QApplication>
#include <QPainter>
#include <QTableWidget>
#include <QHeaderView>
#include <QScrollBar>
#include <QAbstractAnimation>CustomScroll::CustomScroll(QTableView* table,QWidget *parent) : QWidget(parent)
{
#define SRCOLL_HEIGHT 22setAttribute(Qt::WA_TranslucentBackground);m_table = table;m_scrollBar = table->verticalScrollBar();m_table->viewport()->installEventFilter(this);m_table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);animation = new QPropertyAnimation(m_scrollBar,"value",this);connect(&m_scrollTimer,SIGNAL(timeout()),this,SLOT(scrollTimeOut()));connect(&m_selectTimer,SIGNAL(timeout()),this,SLOT(selectTimeOut()));this->setMinimumSize(10, table->height());this->setMaximumSize(10, table->height());this->move(table->width()-10,0); //将滑动条移至最右侧this->raise();m_srcollH = table->height()* SRCOLL_HEIGHT/100.0;
}void CustomScroll::selectTimeOut()
{m_table->selectRow(m_selectRow);m_selectTimer.stop();this->update();
}void CustomScroll::scrollTimeOut()
{if(m_dragFlag == MOUSE_RELEASE_MOVE && animation->state()==QAbstractAnimation::Stopped) //停下来了{this->update();m_dragFlag = MOUSE_RELEASE;m_scrollTimer.setInterval(1000);}else{this->update();if(m_scrollTimer.interval()==1000)m_scrollTimer.stop();}}bool CustomScroll::eventFilter(QObject *obj, QEvent *evt)
{static int pressPoint_y = 0;static int dragPoint_y = -1;static qint64 pressMSec ;QMouseEvent *mouse = dynamic_cast<QMouseEvent *>(evt);int scrollV_max = m_scrollBar->maximum ();int scrollV_min = m_scrollBar->minimum ();//根据鼠标的动作——按下、放开、拖动,执行相应的操作if(mouse){if( mouse->type() ==QEvent::MouseButtonPress) //首次按下{pressMSec = QDateTime::currentDateTime().toMSecsSinceEpoch(); //记录按下的时间dragPoint_y = mouse->pos().y(); //当前坐标pressPoint_y = dragPoint_y; //按下的位置animation->stop();m_selectRow = m_table->indexAt(mouse->pos() ).row(); //选择当前行qDebug()<<mouse->pos()<<m_selectRow;m_selectTimer.start(100);m_dragFlag = MOUSE_PRESS;return true;}else if(mouse->type() == QEvent::MouseButtonRelease && m_dragFlag == MOUSE_PRESS) //未移动{m_dragFlag = MOUSE_RELEASE;if(!m_scrollTimer.isActive())m_scrollTimer.start(1000); //1S后取消滑动条显示return true;}else if(mouse->type() == QEvent::MouseButtonRelease && m_dragFlag == MOUSE_PRESS_MOVE){dragPoint_y = -1;int releasePoint_y = mouse->pos().y();int ms= QDateTime::currentDateTime().toMSecsSinceEpoch()-pressMSec;int Pixel_per_second=qAbs(releasePoint_y - pressPoint_y)*1000/ms; //计算每秒像素点if(Pixel_per_second<300 || qAbs(releasePoint_y - pressPoint_y) < 45){m_dragFlag = MOUSE_RELEASE;if(!m_scrollTimer.isActive())m_scrollTimer.start(1000); //1S后取消滑动条显示return true;}else{int moveValue ;if(ms > 1000) //滑动的时间太长{m_dragFlag = MOUSE_RELEASE;if(!m_scrollTimer.isActive())m_scrollTimer.start(1000); //1S后取消滑动条显示return true;}if(releasePoint_y - pressPoint_y > 0) //向下滑动{moveValue = m_scrollBar->value() - Pixel_per_second*0.2*(300/ms);//滑动时间越长,moveValue值越小,因为不是快速滑动if(moveValue < scrollV_min){moveValue = scrollV_min;}}else{moveValue = m_scrollBar->value() + Pixel_per_second*0.2*(300/ms);if(moveValue > scrollV_max){moveValue = scrollV_max;}}animation->setDuration(2000-ms);animation->setEndValue(moveValue);animation->setEasingCurve(QEasingCurve::OutQuart);if(!m_scrollTimer.isActive())m_scrollTimer.start(50); //定时刷新滑动条显示animation->start();m_dragFlag = MOUSE_RELEASE_MOVE;}return true;}else if(mouse->type() == QEvent::MouseMove && (m_dragFlag!= MOUSE_RELEASE) ){if( m_dragFlag == MOUSE_PRESS) //开始移动{if(qAbs(dragPoint_y - mouse->pos().y()) < 4) //判断移动阀值,避免误操作return true;else{m_dragFlag = MOUSE_PRESS_MOVE;if(m_selectTimer.isActive()) //已经移动了,所以取消选择m_selectTimer.stop();m_table->clearSelection();dragPoint_y = mouse->pos().y(); //获取当前坐标update();return true;}}int moveValue = ( dragPoint_y-mouse->pos().y())+m_scrollBar->value(); //差距dragPoint_y = mouse->pos().y(); //获取当前坐标if(scrollV_min > moveValue){moveValue = scrollV_min;}if(moveValue > scrollV_max){moveValue = scrollV_max;}m_scrollBar->setValue(moveValue);update();return true;}}return QWidget::eventFilter(obj,evt);
}void CustomScroll::paintEvent(QPaintEvent *)
{
#define WIDTH 6 //滑动条的宽度.
#define MIN_HEIGHT 26if(m_dragFlag== MOUSE_RELEASE||m_dragFlag== MOUSE_PRESS){return;}int scrollV_max = m_scrollBar->maximum ();QPainter painter(this);int y = (m_table->verticalScrollBar()->value()*(m_table->height()-m_srcollH))/(float)(scrollV_max);painter.setPen(Qt::NoPen);// painter.setBrush(QColor(180,180,180,200));// painter.drawRoundedRect(0,0,this->width(),this->height(),3,3);painter.setBrush(QColor(80,80,80,140));painter.drawRoundedRect(0,y,WIDTH,m_srcollH,3,3);
}
Form.h
使用:创建界面,创建tableView对象,作为参数创建CustomScroll ,经过处理,tableView对象再添加进界面显示交互。
#ifndef FORM_H
#define FORM_H#include <QWidget>
#include <QStandardItemModel>
namespace Ui {
class Form;
}class Form : public QWidget
{Q_OBJECTpublic:explicit Form(QWidget *parent = nullptr);~Form();private:Ui::Form *ui;
};#endif // FORM_H
Form.cpp
#include "form.h"
#include "ui_form.h"
#include <QTableView>
#include <QHeaderView>
#include "CustomScrollWidget.h"
Form::Form(QWidget *parent): QWidget(parent), ui(new Ui::Form)
{ui->setupUi(this);// 创建一个简单的表格视图QTableView *tableView = new QTableView;QStandardItemModel *model = new QStandardItemModel(/*100, 5*/); // 100 行,5 列for (int var = 0; var < 100; ++var) {QList<QStandardItem*>items;items<<new QStandardItem("111")<<new QStandardItem("222")<<new QStandardItem("333")<<new QStandardItem("444");model->appendRow(items);}tableView->setModel(model);// 创建自定义滚动条CustomScroll *customScroll = new CustomScroll(tableView);ui->verticalLayout->addWidget(tableView);}Form::~Form()
{delete ui;
}