Reputation: 248
I'm using QT Creator to create a simple Application that has two textEdit fields next to each oteher. I want both fields to be linked when it comes to scrolling so that when one field scrolls up or down, the other one will as well automatically and vice versa. For this, I need a callback function that is triggered whenever the user moves the slideBar of one of the fields. Unfortunately, when I right click the textEdit fields and press "Go to slots" I can not find an event for the movement of the slideBar.
How can I achieve this?
Upvotes: 0
Views: 197
Reputation: 2054
QTextEdit
does not have a signal for when the sliderbar in it changes, since it is not a scrollbar. However QScrollBar
has the sliderMoved(int value)
signal which is emitted when the slider moves. QScrollBar
also has a way to set its scroll value via slots (with setValue(int value)
)
We can therefore tie two scrollbars together using signals and slots very easily.
For example:
...
// Get easy pointers to the scrollbars
QScrollBar* textbx_slider_1 = ui->textbx1->verticalScrollBar();
QScrollBar* textbx_slider_2 = ui->textbx2->verticalScrollBar();
// Connect them too each other
connect(textbx_slider_1, &QScrollBar::sliderMoved, textbx_slider_2, &QScrollBar::setValue); // Connect the first scrollbar to the second
connect(textbx_slider_2, &QScrollBar::sliderMoved, textbx_slider_1, &QScrollBar::setValue); // Connect the second scrollbar to the first
...
(This assumes that your QTextEdit
widgets have ids' of textbx1
and textbx2
)
Edit:
It is worth mentioning that sliderMoved
will not be emitted when using the scroll wheel on the text box. To detect those inputs you must use something like QScrollBar::valueChanged
. You have to be careful with this however since setValue
emits valueChanged
, meaning you will get an infinite feedback loop if you simply modify the above code.
To prevent this you could use a lambda, something like this:
...
int old_pos = textbx_slider_1->value()
std::function<void(int, QScrollBar*)> f = [old_pos](int new_pos, QScrollBar* slider){
if (new_pos != old_pos) {
// Only trigger if the value has changed
slider->setValue(new_pos);
old_pos = new_pos;
};
connect(textbx_slider_1, &QScrollBar::sliderMoved, std::bind(f, std::placeholders::_1, textbx_slider_2)); // Connect the first scrollbar to the second
connect(textbx_slider_2, &QScrollBar::sliderMoved, std::bind(f, std::placeholders::_1, textbx_slider_1)); // Connect the second scrollbar to the first
...
(The weirdness with std::bind()
is simply so we don't repeat virtually the same lambda twice)
Upvotes: 1