1

I'm trying to implement a custom scrolling behavior in a QTextEdit control. It seems to be working but I'm having problems with the PageDown/PageUp key press: I'm controlling the scrolling behavior through the actionTriggered signal since the documentation states:

When the signal is emitted, the sliderPosition has been adjusted according to the action, but the value has not yet been propagated (meaning the valueChanged() signal was not yet emitted), and the visual display has not been updated. In slots connected to this signal you can thus safely adjust any action by calling setSliderPosition() yourself, based on both the action and the slider's value.

and starting a QTimer with the sliderPosition I need to reach from there (e.g. I'm incrementing each time value() to reach sliderPosition). Unfortunately every time I press a PageUp/PageDown key there's also another setValue() function call triggered by the caret which gets moved by the PageUp/PageDown key which moves automatically the scrollbar value to the end of the animation.

The call stack shows:

QAbstractSlider::setValue(int)
??
QMetaObject::activate(QObject*, int, int, void**)   
QWidgetTextControl::visibilityRequest(QRectF const&)    
QWidgetTextControl::ensureCursorVisible()  <--
QWidgetTextControl::setTextCursor(QTextCursor const&)   <--
QTextEdit::keyPressEvent(QKeyEvent*)
QWidget::event(QEvent*)
QFrame::event(QEvent*)
QAbstractScrollArea::event(QEvent*)
QTextEdit::event(QEvent*)
QApplicationPrivate::notify_helper(QObject*, QEvent*)
QApplication::notify(QObject*, QEvent*)
QCoreApplication::notifyInternal(QObject*, QEvent*)
...

I have no idea of how to prevent the caret from issuing that QAbstractSlider::SetValue() call when the caret is moved due to the PageUp/PageDown key press.

Any help would be highly appreciated.

Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • Have you tried to `QObject::disconnect` the SetValue signal? – Thomas Sep 21 '14 at 14:19
  • It couldn't work Thomas because I was relying on the `setValue()` method myself – Marco A. Sep 21 '14 at 18:28
  • Maybe i misunderstood, but i did not mean to disconnect `setValue()` entirely, just the specific connection `disconnect(receiver, SLOT(setValue...), unwanted_sender, SIGNAL(...))`, which should leave you all options to use setValue - possibly by a new connection you install. Nevertheless, since it works now ... ;) – Thomas Sep 21 '14 at 20:59
  • Oh now I got it, sorry :) Yes, that could have worked as well I suppose. It's another way of doing it and quite creative I'd say. If you post an answer with that, I'll accept it (my solution is more involved and I had to radically change the logic behind). – Marco A. Sep 21 '14 at 22:33

2 Answers2

1

OKay, so just use

disconnect(receiver, SLOT(setValue...), unwanted_sender, SIGNAL(...))

to break the specific unwanted connection.

Thomas
  • 725
  • 4
  • 14
0

After a day of research I found the solution thanks to PapierKorb:

  • I used QPropertyAnimation instead of a hand-made QTimer handling on the value property

  • I installed a key event filter for the parent control in order to catch PageDown/PageUp events (installEventFilter) and had the ScrollBar handle all the scrolling behavior. At the end of the animation I manually moved the cursor to the new position without sending any setValue signals

Marco A.
  • 43,032
  • 26
  • 132
  • 246