2

マウスがQTextEdit上にないときにマウスホイールを回すと、そのような場合にスクロールバーは移動しませんが、それでもマウスホイールでスクロールバーを移動したいので、どうすればこの機能を実装できますか? Microsoft Word などの一部のソフトウェアにこの機能があることは知っています。

この機能を以下のように実装したのですが、マウスホイールでスクロールバーを上または下に移動すると、エラーが発生しました: Python オブジェクトの呼び出し中に再帰の最大深度を超えました。誰でも助けることができますか?ここの私のコードhttp://codepad.org/1rq06qTk :

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *


class BoxLayout(QWidget):
    def __init__(self, parent=None):
        super(BoxLayout, self).__init__(parent)
        self.resize(100, 300)

        ok = QPushButton("OK")
        cancel = QPushButton("Cancel")
        self.textEdit = QTextEdit("This function returns true if the contents "
                                  "of the MIME data object, specified by source, "
                                  "can be decoded and inserted into the document. "
                                  "It is called for example when during a drag "
                                  "operation the mouse enters this widget and it "
                                  "is necessary to determine whether it is possible "
                                  "to accept the drag and drop operation.")

        vbox = QVBoxLayout()
        vbox.addWidget(self.textEdit)
        vbox.addWidget(ok)
        vbox.addWidget(cancel)
        self.setLayout(vbox)

#       self.textEdit.installEventFilter(self)


#    def eventFilter(self, obj, event):
#        if obj == self.textEdit:
#            if event.type() == QEvent.Wheel:
#                self.textEdit.wheelEvent(event)
#                return True
#            else:
#                return False
#        else:
#            return QMainWindow.eventFilter(self, obj, event)


    def wheelEvent(self, event):
        self.textEdit.wheelEvent(event)


app = QApplication(sys.argv)
qb = BoxLayout()
qb.show()
sys.exit(app.exec_())
4

2 に答える 2

1

これを行うには、マウス ホイール イベントを QTextEdit に転送するウィジェットにイベント フィルターをインストールします。

残念ながら、C++ コードしか提供できませんが、一般的なアイデアは得られるはずです。また、Qt 4.6.1 を使用しています。Qt 4.8 以降で新しい「スクロール」イベント タイプを検出しました。これを使用する場合は、コードを変更する必要があるかもしれません。


[編集:]

TextEdit のスクロールでは、何らかの理由でイベント処理が標準的な方法とは異なります。ホイール イベントをテキスト エディットに送信しても処理されません。代わりに、残念ながら保護されwheelEventているある種のプライベート イベント フィルター呼び出しが使用されます。QAbstractScrollArea::viewportEvent

簡単に言うと、QTextEdit をサブクラス化することで Wheel イベントを偽装できます。

#include "MyTextEdit.h"

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

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

デフォルトの QTextEdits の代わりにこれを使用する場合、次のように Event Forwarder を作成できます。


#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のドキュメントを参照してください。

于 2013-07-19T07:05:21.297 に答える
0

このアプローチを使用することもできます。

QTextEdit.scroll(int,int) 関数を呼び出して、必要に応じて qtextedit をスクロールします。ウィジェットの mouseScrollEvent からこの関数を呼び出すことができることを意味します

于 2013-07-20T09:37:57.630 に答える