2016-02-12 85 views
0

我有一个窗口,其中是一个QGraphicsView,它将显示图像。我已经实现了wheelEvent()。我的图像大多比窗口大,所以我在窗口中看到滚动条。Qt 5:缩放图像的鼠标滚轮事件行为

当我们转动车轮,同时查看Windows照片查看器中的图像是,当我们移动轮向上(向它的线),在图像放大和我们通常观察到时,我们将其移动(朝排出体外) ,图像缩小。

我得到的是当我向自己移动轮子(缩小图像)而不是缩小图像时,首先向下滚动,并且只有当滚动条接触其最底部点时才开始缩小。

通过尝试代码来理解问题会更好。我猜我无法解释。

我想要标准的行为。该怎么办?

代码

#include "viewer.h" 
#include "ui_viewer.h" 
#include <QGraphicsView> 
#include <QGraphicsItem> 
#include <QGraphicsPixmapItem> 
#include <QWheelEvent> 
#include <QDebug> 
#include <QImage> 
#include <QImageReader> 
#include <QApplication> 
#include <QDesktopWidget> 

viewer::viewer(QWidget *parent) : QWidget(parent),ui2(new Ui::viewer) 
{ 
    ui2->setupUi(this); 
} 

viewer::~viewer() 
{ 
    delete ui2; 
} 

int viewer::show_changes(QString folder) 
{ 
    QDesktopWidget *desktop = QApplication::desktop(); 
    int screenWidth = desktop->width(); 
    int screenHeight = desktop->height(); 
    QString filename = "image_bigger_than_window.jpg"; 
    QPixmap pixmap = QPixmap(filename); 
    QImageReader reader(filename); 
    QImage image = reader.read(); 
    QSize size = image.size(); 
    int width = 800; 
    int height = (width * size.height())/size.width(); 
    int x = (screenWidth - width)/2; 
    int y = (screenHeight - height)/2 - 30; 
    setGeometry(x,y,width, height); 
    setWindowTitle("OUTPUT"); 
    ui2->graphicsView->setGeometry(0,0,width,height); 
    QGraphicsScene* viewScene = new QGraphicsScene(QRectF(0, 0,width, height), 0); 
    QGraphicsPixmapItem *item = viewScene->addPixmap(pixmap.scaled(QSize((int)viewScene->width(), (int)viewScene->height()), 
          Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); 
    viewScene->addItem(item); 
    ui2->graphicsView->fitInView(QRectF(0, 0, width,  height),Qt::IgnoreAspectRatio); 
    ui2->graphicsView->setScene(viewScene); 
    ui2->graphicsView->show(); 
    return 0; 
} 

void viewer::wheelEvent(QWheelEvent * event) 
{ 
    const int degrees = event->delta()/8; 
    qDebug() << degrees; 
    int steps = degrees/15;   
    double scaleFactor = 1.0; 
    const qreal minFactor = 1.0; 
    const qreal maxFactor = 10.0; 
    qreal h11 = 1.0, h22 = 0; 
    if(steps > 0) 
    { 
     h11 = (h11 >= maxFactor) ? h11 : (h11 + scaleFactor); 
     h22 = (h22 >= maxFactor) ? h22 : (h22 + scaleFactor); 
    } 
    else 
    { 
     h11 = (h11 <= minFactor) ? minFactor : (h11 - scaleFactor); 
     h22 = (h22 <= minFactor) ? minFactor : (h22 - scaleFactor); 
    } 
    ui2->graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); 
    ui2->graphicsView->setTransform(QTransform(h11, 0, 0,0, h22, 0, 0,0,1)); 

} 

EDIT

1)删除功能void viewer::wheelEvent(QWheelEvent * event)viewer.cpp

2)将bool viewer::eventFilter(QObject *obj, QEvent *event)在其位置作为受保护的功能和void viewer::handleWheelOnGraphicsScene(QGraphicsSceneWheelEvent* scrollevent)作为一种公开槽viewer.h

bool viewer::eventFilter(QObject *obj, QEvent *event) 
{ 
    if (event->type() == QEvent::GraphicsSceneWheel) 
    {  
     QGraphicsSceneWheelEvent *scrollevent = static_cast<QGraphicsSceneWheelEvent *>(event); 
     handleWheelOnGraphicsScene(scrollevent); 
     return true; 
    } 
    // Other events should propagate - what do you mean by propagate here? 
    return false; 
} 

void viewer::handleWheelOnGraphicsScene(QGraphicsSceneWheelEvent* scrollevent) 
{ 
    const int degrees = scrollevent->delta()/8; 
    qDebug() << degrees; 
    int steps = degrees/15; 
    qDebug() << steps; 
    double scaleFactor = 1.0; //How fast we zoom 
    const qreal minFactor = 1.0; 
    const qreal maxFactor = 10.0; 
    if(steps > 0) 
    { 
     h11 = (h11 >= maxFactor) ? h11 : (h11 + scaleFactor); 
     h22 = (h22 >= maxFactor) ? h22 : (h22 + scaleFactor); 
    } 
    else 
    { 
     h11 = (h11 <= minFactor) ? minFactor : (h11 - scaleFactor); 
     h22 = (h22 <= minFactor) ? minFactor : (h22 - scaleFactor); 
    } 
ui2->graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); 
ui2->graphicsView->setTransform(QTransform(h11, 0, 0,0, h22, 0, 0,0,1)); 

} 
+0

传播我的意思是事件在一个链中处理。当事件发送到一个不处理它的小部件(例如按钮上的滚轮事件)时,它将被传播到它的父小部件,以便它能够处理它(例如包含该按钮的滚动视图)。这同样适用于事件过滤器。 –

回答

2

该代码显示您没有子类QGraphicsView,而是在您自己的小部件中使用一个。

车轮事件将首先发送到实际的图形视图控件。在那里用Qt的默认行为处理,即滚动。只有滚动到底部时,图形视图才能处理轮子事件,并将其传播到其父级,即班级。这就是为什么只有在滚动到边框时才能缩放。

要解决此问题,您应该install an event filter。这让你拦截滚轮事件并处理它在你的类:

// Outline, not tested 
viewer::viewer(QWidget *parent) : QWidget(parent),ui2(new Ui::viewer) 
{ 
    ui2->setupUi(this); 
    // Let me handle your events 
    ui2->graphicsView->installEventFilter(this); 
} 

// should be protected 
bool viewer::eventFilter(QObject *obj, QEvent *event) { 
    if (event->type() == QEvent::GraphicsSceneWheel) { 
     // Your implementation. 
     // You can't use QWheelEvent, as Graphicscene works with its own events... 
    handleWheelOnGraphicsScene(static_cast<QGraphicsSceneWheelEvent*> (event)); 

    // Don't propagate 
    return true; 
    } 

    // Other events should propagate 
    return false; 
} 

更新
我只是想出了该事件过滤器将不会收到该图形视图GraphicsSceneWheel事件。相反,您必须在图形场景上安装筛选器。此外,您必须致电event->accept(),以便它不会传播。

所以更新的代码:

// In Constructor, or where appropriate 
ui2->graphicsView->scene()->installEventFilter(this); 


bool viewer::eventFilter(QObject *obj, QEvent *event) { 
    if (event->type() == QEvent::GraphicsSceneWheel) { 
     handleWheelOnGraphicsScene(static_cast<QGraphicsSceneWheelEvent*> (event)); 

     // Don't propagate 
     event->accept(); 
     return true; 
    } 
    return false; 
} 

也注意到,handleWheelOnGraphicsScene或者随便你怎么称呼它,应该是一个私有方法,而不必是一个插槽。

+0

我对代码做了一些更改。现在我的图像根本不滚动。它只在滚动轮子时上下移动。什么地方出了错? – Nancy

+0

一切正常,因为我想要的。感谢您的帮助。 – Nancy