qgraphicsview 水平滚动总是有一个垂直增量
Posted
技术标签:
【中文标题】qgraphicsview 水平滚动总是有一个垂直增量【英文标题】:qgraphicsview horizontal scrolling always has a vertical delta 【发布时间】:2013-05-10 05:08:59 【问题描述】:我将 QGraphicsView 子类化为要在 CAD 应用程序中使用的自定义画布。我已经成功地重新实现了 QGraphicsView::wheelEvent 来检查控制键的键盘修饰符,如果按下控制键,则进行缩放。当用户按住 shift 并使用滚轮时,我正在尝试实现水平滚动。
我遇到的问题是水平滚动也总是向上滚动 0.279。不是一个大问题,但非常烦人,它表明还有其他问题。
所以,这里有问题:
-
这是实现水平滚动的正确方法吗?如果不是,是什么?
如何消除这个 0.279 的增量?
提前致谢。下面的代码和示例输出
void myView::zoom(int delta)
double factor = pow(1.2, delta/abs(delta));
this->scale(factor, factor);
void myView::scrollHorizontal(int level)
QPointF center = mapToScene(viewport()->rect().center());
qDebug() << "center: " << center.x() << ", " << center.y();
centerOn(QPointF(center.x() - level, center.y()));
void myView::wheelEvent(QWheelEvent *event)
//qDebug() << "delta: " << event->delta();
if (event->modifiers() & Qt::ControlModifier)
this->zoom(event->delta());
else if (event->modifiers() & Qt::ShiftModifier)
this->scrollHorizontal(event->delta());
else
QGraphicsView::wheelEvent(event);
scrollHorizontal 中 qDebug() 行在场景左边缘时的示例输出:
center: 261.5 , 615.654
center: 261.5 , 615.375
center: 261.5 , 615.096
center: 261.5 , 614.817
center: 261.5 , 614.538
center: 261.5 , 614.259
center: 261.5 , 613.98
center: 261.5 , 613.701
center: 261.5 , 613.421
【问题讨论】:
这很奇怪。当您到达场景矩形的边界时,我确实发现QGraphicsView
滚动有点“不自然”,无论可见矩形在场景矩形中的哪个位置,行为是否相同?
虽然知道是什么导致了这个问题会很有趣,但从UX 的角度来看,你正在做的事情非常糟糕。如果有人想要水平滚动,他们可以简单地使用实现了它的输入设备。像所有最近的触控板、带有滚动板或多点触控的鼠标等。大概,CAD 用户可以负担得起一个不错的输入设备,而您不需要提供这样的解决方法。
【参考方案1】:
您的问题来自 mapToScene()
处理整数点,而不是浮点数。对于特定视口大小,舍入误差始终以相同的方式指向,因此您总是添加一些增量。
您想直接修改滚动条的value
属性或将事件发送到水平滚动条。后者我实现了,很简单。
在 Mac 上,您必须绝对禁用应用程序的滚动条惯性。否则,一旦您松开修改器并将手指从触控板/滚轮上抬起,由于惯性,垂直滚动将继续。这会让 Mac 用户的体验变得糟糕,他们会因此而讨厌你 :)
gview-scroll.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = gview-scroll
TEMPLATE = app
macx
LIBS += -framework Foundation
OBJECTIVE_SOURCES += helper.m
SOURCES += main.cpp
helper.m
//helper.m
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSString.h>
void disableMomentumScroll(void)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"NO" forKey:@"AppleMomentumScrollSupported"];
[defaults registerDefaults:appDefaults];
main.cpp
//main.cpp
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QtCore/qmath.h>
#include <QScrollBar>
#include <QWheelEvent>
#include <QDebug>
class View : public QGraphicsView
public:
void zoom(int delta)
double factor = qPow(1.2, delta/qAbs(delta));
scale(factor, factor);
void wheelEvent(QWheelEvent *event)
if (event->modifiers() & Qt::ControlModifier)
zoom(event->delta());
else if (event->modifiers() & Qt::ShiftModifier)
horizontalScrollBar()->event(event);
else
QGraphicsView::wheelEvent(event);
public:
explicit View(QWidget *parent=0) : QGraphicsView(parent)
explicit View(QGraphicsScene *scene, QWidget *parent=0) : QGraphicsView(scene, parent)
;
#ifndef Q_OS_MAC
void disableMomentumScroll()
#else
extern "C" void disableMomentumScroll();
#endif
int main(int argc, char *argv[])
QApplication a(argc, argv);
disableMomentumScroll();
QGraphicsScene s;
s.addEllipse(-50, -50, 100, 100, QPen(Qt::red), QBrush(Qt::gray));
View w(&s);
w.show();
return a.exec();
【讨论】:
以上是关于qgraphicsview 水平滚动总是有一个垂直增量的主要内容,如果未能解决你的问题,请参考以下文章
停止 Qt QGraphicsView 在重新调整大小时滚动
水平 UIScrollView 内部有垂直 UIScrollViews - 滚动外部水平视图时如何防止滚动内部滚动视图?