如何将QWidget的Wheel事件重定向到QTextEdit

时间:2013-07-19 05:56:06

标签: qt qt4 pyqt pyqt4 pyside

当鼠标不在QTextEdit上时转动鼠标滚轮,滚动条在这种情况下不会移动,但我仍然想用鼠标滚轮移动滚动条,那么我该如何实现这个功能呢? 我知道像Microsoft Word这样的软件有这个功能。

我实现了以下功能,但是当您通过鼠标滚轮将滚动条移动到顶部或底部时,会发生错误:调用Python对象时超出了最大递归深度。 谁有人可以帮忙? 我的代码http://codepad.org/1rq06qTk

2 个答案:

答案 0 :(得分:1)

您可以通过在任何小部件上安装事件过滤器来实现此目的,该小部件将鼠标滚轮事件转发到QTextEdit:

遗憾的是,我只能给你C ++代码,但它应该给你一个大致的想法。 另外,我正在使用Qt 4.6.1。我在Qt 4.8及更高版本中检测到一个新的“Scroll”事件类型,您可能需要在使用时更改代码。


[编辑:]

对于TextEdit滚动,由于某些原因,事件处理与标准方式不同: 将轮子事件发送到文本编辑不会处理它。 相反,某种私人事件过滤器会调用wheelEventQAbstractScrollArea::viewportEvent,但不幸的是会受到保护。

长话短说,我们可以通过继承QTextEdit来伪造Wheel事件:

#include "MyTextEdit.h"

MyTextEdit::MyTextEdit( QWidget* parent ) :
    QTextEdit( parent )
{
}

void MyTextEdit::forwardViewportEvent( QEvent* event )
{
    viewportEvent( event );
}

使用此代替默认的QTextEdits时,您可以像这样创建一个事件转发器:


#ifndef WHEELEVENTFORWARDER_H
#define WHEELEVENTFORWARDER_H

#include <QtCore/QObject>

class MyTextEdit;

class WheelEventForwarder : public QObject
{
    Q_OBJECT
public:
    explicit WheelEventForwarder( MyTextEdit* target );
    ~WheelEventForwarder();

    bool eventFilter( QObject* obj, QEvent* event );

private:
    MyTextEdit* _target;
};

#endif // WHEELEVENTFORWARDER_H

WheelEventForwarder.cpp

#include "WheelEventForwarder.h"
#include "MyTextEdit.h"
#include <QtCore/QEvent>
#include <QtGui/QApplication>

WheelEventForwarder::WheelEventForwarder( MyTextEdit* target ) :
    QObject(),
    _target( target )
{
}

WheelEventForwarder::~WheelEventForwarder()
{
    _target = NULL;
}

bool WheelEventForwarder::eventFilter( QObject* obj, QEvent* event )
{
    Q_UNUSED( obj );

    static bool recursionProtection = false;

    if( recursionProtection ) return false;

    if( !_target ) return false;

    if( event->type() == QEvent::Wheel )
    {
        recursionProtection = true;
        _target->forwardViewportEvent( event );
        recursionProtection = false;
    }

    // do not filter the event
    return false;
}

然后你可以像这样安装一个事件过滤器:

MainWindow.cpp(或任何更合适的地方):

_wheelEventForwarder = new WheelEventForwarder( ui->textEdit );

ui->centralwidget->installEventFilter( _wheelEventForwarder );

有关详细信息,请参阅QObject::installEventFilter的文档。

答案 1 :(得分:0)

你也可以采用这种方法:

调用QTextEdit.scroll(int,int)函数以在需要时滚动qtextedit。 意味着您可以从小部件的mouseScrollEvent中调用此函数