1515#include < QEvent>
1616#include < QHoverEvent>
1717#include < QScrollBar>
18+ #include < QCoreApplication>
1819#include < QScroller>
1920#include < QScrollerProperties>
2021#include < QSortFilterProxyModel>
@@ -66,6 +67,8 @@ NetView::NetView(NetManager *manager)
6667 setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
6768 setVerticalScrollBarPolicy (Qt::ScrollBarAsNeeded);
6869 setSizeAdjustPolicy (QAbstractScrollArea::AdjustToContents);
70+ setVerticalScrollMode (QAbstractItemView::ScrollPerPixel);
71+ setHorizontalScrollMode (QAbstractItemView::ScrollPerPixel);
6972
7073 setSelectionMode (QAbstractItemView::NoSelection);
7174 setRootIsDecorated (false );
@@ -83,13 +86,8 @@ NetView::NetView(NetManager *manager)
8386 connect (this , &NetView::activated, this , &NetView::onActivated);
8487
8588 // 支持在触摸屏上滚动
86- QScroller::grabGesture (viewport (), QScroller::TouchGesture);
87- QScrollerProperties sp = QScroller::scroller (viewport ())->scrollerProperties ();
88- sp.setScrollMetric (QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
89- sp.setScrollMetric (QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
90- sp.setScrollMetric (QScrollerProperties::DecelerationFactor, 0.5 );
91- sp.setScrollMetric (QScrollerProperties::MaximumVelocity, 0.5 );
92- QScroller::scroller (viewport ())->setScrollerProperties (sp);
89+ setAttribute (Qt::WA_AcceptTouchEvents, true );
90+ viewport ()->setAttribute (Qt::WA_AcceptTouchEvents, true );
9391}
9492
9593NetView::~NetView () = default ;
@@ -183,6 +181,72 @@ void NetView::rowsInserted(const QModelIndex &parent, int start, int end)
183181
184182bool NetView::viewportEvent (QEvent *event)
185183{
184+ static QPointF s_touchPressPos;
185+ static bool s_isDrag = false ;
186+
187+ const QEvent::Type type = event->type ();
188+ if (type == QEvent::TouchBegin || type == QEvent::TouchUpdate ||
189+ type == QEvent::TouchEnd || type == QEvent::TouchCancel) {
190+
191+ QTouchEvent *te = static_cast <QTouchEvent *>(event);
192+ if (te->points ().isEmpty ()) {
193+ event->accept ();
194+ return true ;
195+ }
196+
197+ QEventPoint pt = te->points ().first ();
198+
199+ switch (type) {
200+ case QEvent::TouchBegin: {
201+ s_touchPressPos = pt.globalPosition ();
202+ s_isDrag = false ;
203+ break ;
204+ }
205+ case QEvent::TouchUpdate: {
206+ qreal deltaY = pt.globalPosition ().y () - s_touchPressPos.y ();
207+ qreal deltaX = pt.globalPosition ().x () - s_touchPressPos.x ();
208+
209+ if (!s_isDrag && (qAbs (deltaY) >= QApplication::startDragDistance () || qAbs (deltaX) >= QApplication::startDragDistance ())) {
210+ s_isDrag = true ;
211+ }
212+
213+ if (s_isDrag) {
214+ if (qAbs (deltaY) > 0 && verticalScrollBar ()) {
215+ verticalScrollBar ()->setValue (verticalScrollBar ()->value () - deltaY);
216+ }
217+ if (qAbs (deltaX) > 0 && horizontalScrollBar ()) {
218+ horizontalScrollBar ()->setValue (horizontalScrollBar ()->value () - deltaX);
219+ }
220+ s_touchPressPos = pt.globalPosition ();
221+ }
222+ break ;
223+ }
224+ case QEvent::TouchEnd: {
225+ if (!s_isDrag) {
226+ // Determine the correct target widget for the click
227+ QWidget *target = viewport ();
228+ QPoint widgetPos = pt.position ().toPoint ();
229+
230+ if (QWidget *child = target->childAt (widgetPos)) {
231+ target = child;
232+ widgetPos = target->mapFrom (viewport (), widgetPos);
233+ }
234+
235+ QMouseEvent press (QEvent::MouseButtonPress, widgetPos, pt.globalPosition (), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
236+ QCoreApplication::sendEvent (target, &press);
237+ QMouseEvent release (QEvent::MouseButtonRelease, widgetPos, pt.globalPosition (), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
238+ QCoreApplication::sendEvent (target, &release);
239+ }
240+ break ;
241+ }
242+ default :
243+ break ;
244+ }
245+
246+ event->accept ();
247+ return true ;
248+ }
249+
186250 switch (event->type ()) {
187251 case QEvent::HoverLeave: {
188252 setCurrentIndex (QModelIndex ());
0 commit comments