我已经将QGraphicsView子类化为CAD应用程序中使用的自定义画布。我已成功重新实现QGraphicsView :: wheelEvent以检查控制键的键盘修改器,如果按下控制键,则进行缩放。当用户保持移位并使用滚轮时,我试图实现水平滚动。
我遇到的问题是水平滚动始终向上滚动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
答案 0 :(得分:5)
您的问题来自于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();
}