我正在使用QT创建一个简单的应用程序,该应用程序在每个oteher旁边有两个textEdit字段。我希望这两个字段在滚动时被链接,这样当一个字段向上或向下滚动时,另一个字段也会自动滚动,反之亦然。为此,我需要一个回调函数,每当用户移动其中一个字段的slideBar时,就会触发该回调函数。不幸的是,当我右键单击textEdit字段并按“转到时隙”时,我无法找到slideBar移动的事件。
我怎样才能做到这一点?
发布于 2020-04-15 12:38:20
由于QTextEdit不是滚动条,因此它中的滑块何时发生变化没有信号。然而,QScrollBar具有当滑块移动时发出的sliderMoved(int value)信号。QScrollBar还有一种通过插槽设置滚动值的方法(使用setValue(int value))。
因此,我们可以很容易地使用信号和插槽将两个滚动条连接在一起。
例如:
...
// 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
...(这假定QTextEdit小部件具有textbx1和textbx2的ids‘)
编辑:
值得一提的是,当使用文本框上的滚动轮时,sliderMoved将发出而不是。要检测这些输入,您必须使用类似于QScrollBar::valueChanged的东西。但是,您必须小心,因为setValue 会发出 valueChanged,这意味着只要简单地修改上面的代码,您就会得到一个无限的反馈循环。
为了防止出现这种情况,您可以使用lambda,如下所示:
...
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
...( std::bind()的怪异之处很简单,所以我们不会重复两次相同的λ)
https://stackoverflow.com/questions/61228478
复制相似问题