简体   繁体   中英

C++ QT Creator create slot function for QTextEdit::verticalSlideBar?

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?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM