C++ 如何同步两个QListWidget的滚动?
有两个C++ 如何同步两个QListWidget的滚动?,c++,qt,qt5,qlistwidget,C++,Qt,Qt5,Qlistwidget,有两个QListWidget具有相同的项目数。如何同步他们的滚动 我的意思是当我滚动其中一个时,另一个应该得到相同的滚动 您必须使用QListWidget的verticalScrollBar()中的valueChanged()信号,因为连接是双向的,这将导致使用blockSignals()为其执行不必要的任务: 在下一节中,我将展示一个示例: #include <QApplication> #include <QListWidget> #include <QHBox
QListWidget
具有相同的项目数。如何同步他们的滚动
我的意思是当我滚动其中一个时,另一个应该得到相同的滚动 您必须使用
QListWidget
的verticalScrollBar()
中的valueChanged()
信号,因为连接是双向的,这将导致使用blockSignals()
为其执行不必要的任务:
在下一节中,我将展示一个示例:
#include <QApplication>
#include <QListWidget>
#include <QHBoxLayout>
#include <QScrollBar>
class Widget: public QWidget{
Q_OBJECT
QListWidget w1;
QListWidget w2;
public:
Widget(QWidget *parent=Q_NULLPTR):QWidget(parent){
auto layout = new QHBoxLayout{this};
layout->addWidget(&w1);
layout->addWidget(&w2);
connect(w1.verticalScrollBar(), &QScrollBar::valueChanged, [this](int value){
w2.verticalScrollBar()->blockSignals(true);
w2.verticalScrollBar()->setValue(value);
w2.verticalScrollBar()->blockSignals(false);
});
connect(w2.verticalScrollBar(), &QScrollBar::valueChanged, [this](int value){
w1.verticalScrollBar()->blockSignals(true);
w1.verticalScrollBar()->setValue(value);
w1.verticalScrollBar()->blockSignals(false);
});
for(int i=0; i<100; i++){
w1.addItem(QString("item %1 of 1").arg(i));
w2.addItem(QString("item %1 of 2").arg(i));
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
#包括
#包括
#包括
#包括
类Widget:publicqwidget{
Q_对象
qlistw1;
qlistw2;
公众:
小部件(QWidget*parent=Q_NULLPTR):QWidget(parent){
自动布局=新的QHBoxLayout{this};
布局->添加小部件(&w1);
布局->添加小部件(&w2);
连接(w1.verticalScrollBar(),&QScrollBar::valueChanged,[this](int-value){
w2.垂直滚动条()->块信号(true);
w2.垂直滚动条()->设置值(值);
w2.垂直滚动条()->块信号(假);
});
连接(w2.verticalScrollBar(),&QScrollBar::valueChanged,[this](int-value){
w1.垂直滚动条()->块信号(真);
w1.垂直滚动条()->设置值(值);
w1.垂直滚动条()->块信号(假);
});
对于(int i=0;i假设您在UI
中有两个QListWidget
元素listWidget_1
和listWidget_2
,那么您可以使用valueChanged
/setValue
signal/slot对来连接这两个listWidget的垂直滑块,事实上,我没有发现任何信号反弹的问题“双向”连接,因为最终两个值将相同,并且我认为不会发出更多信号,因此您可以设置足够的连接:
connect(this->ui->listWidget_1->verticalScrollBar(), &QScrollBar::valueChanged,
this->ui->listWidget_2->verticalScrollBar(), &QScrollBar::setValue);
connect(this->ui->listWidget_2->verticalScrollBar(), &QScrollBar::valueChanged,
this->ui->listWidget_1->verticalScrollBar(), &QScrollBar::setValue);
// test lists:
QList<QString> lw11, lw22;
for (int x=0; x <200; x++){
lw11.append("ListWidget1_" + QVariant(x).toString());
lw22.append("The Other lw is at: " + QVariant(x).toString());
}
this->ui->listWidget_1->addItems(lw11);
this->ui->listWidget_2->addItems(lw22);
插槽逻辑可以是:
void MainWindow::handleScroll(int value)
{
// Logic for detecting sender() can be used ... but I don't see it's important
// fast way to check which listWidget emitted the signal ...
if (this->ui->listWidget_1->verticalScrollBar()->value() == value){
qDebug() << "lw1 is in charge ...............";
disconnect(this->ui->listWidget_2->verticalScrollBar(), &QScrollBar::valueChanged,this, &MainWindow::handleScroll); // prevent signal rebounce from the other lw
this->ui->listWidget_2->verticalScrollBar()->setValue(value);
connect(this->ui->listWidget_2->verticalScrollBar(), &QScrollBar::valueChanged,this, &MainWindow::handleScroll);
}else{
qDebug() << "lw2 is in charge ...............";
disconnect(this->ui->listWidget_1->verticalScrollBar(), &QScrollBar::valueChanged,this, &MainWindow::handleScroll);
this->ui->listWidget_1->verticalScrollBar()->setValue(value);
connect(this->ui->listWidget_1->verticalScrollBar(), &QScrollBar::valueChanged,this, &MainWindow::handleScroll);
}
}
void主窗口::handleScroll(int值)
{
//可以使用检测发送者()的逻辑…但我不认为这很重要
//检查哪个listWidget发出信号的快速方法。。。
如果(此->ui->列表小部件\u 1->垂直滚动条()->value()==value){
qDebug()ui->listWidget_2->verticalScrollBar(),&QScrollBar::valueChanged,this,&MainWindow::handleScroll);//防止从其他lw重新启动信号
此->用户界面->列表小部件\u 2->垂直滚动条()->设置值(值);
连接(this->ui->listWidget_2->verticalScrollBar(),&QScrollBar::valueChanged,this,&MainWindow::handleScroll);
}否则{
qDebug()ui->listWidget_1->verticalScrollBar(),&QScrollBar::valueChanged,this,&MainWindow::handleScroll);
此->用户界面->列表小部件\u 1->垂直滚动条()->设置值(值);
连接(this->ui->listWidget_1->verticalScrollBar(),&QScrollBar::valueChanged,this,&MainWindow::handleScroll);
}
}
我的解决方案有效吗?@eyllanesc需要同步更新。在答案中添加了注释。滚动条已同步。但图片仅在光标下更新。blockSignals()用于同步的工作不正确-内容不滚动。仅valueChanged()
signal disconnect/connect工作正常。@AlekseyKontsevich它对我工作正常,你为什么说它不工作?,“connect and disconnect”一点也不优雅。@eyllanesc,正如我说的,在这种情况下,内容不会滚动,只有滚动条。@AlekseyKontsevich好吧,我觉得奇怪,你用了我的例子,什么版本的Qt你用什么?
void MainWindow::handleScroll(int value)
{
// Logic for detecting sender() can be used ... but I don't see it's important
// fast way to check which listWidget emitted the signal ...
if (this->ui->listWidget_1->verticalScrollBar()->value() == value){
qDebug() << "lw1 is in charge ...............";
disconnect(this->ui->listWidget_2->verticalScrollBar(), &QScrollBar::valueChanged,this, &MainWindow::handleScroll); // prevent signal rebounce from the other lw
this->ui->listWidget_2->verticalScrollBar()->setValue(value);
connect(this->ui->listWidget_2->verticalScrollBar(), &QScrollBar::valueChanged,this, &MainWindow::handleScroll);
}else{
qDebug() << "lw2 is in charge ...............";
disconnect(this->ui->listWidget_1->verticalScrollBar(), &QScrollBar::valueChanged,this, &MainWindow::handleScroll);
this->ui->listWidget_1->verticalScrollBar()->setValue(value);
connect(this->ui->listWidget_1->verticalScrollBar(), &QScrollBar::valueChanged,this, &MainWindow::handleScroll);
}
}