如何同步两个QListWidgets的滚动



有两个项目数相同的QListWidget。如何同步他们的滚动?

我的意思是当我滚动其中一个时,另一个应该得到相同的滚动。

假设您的UI中有两个QListWidget元素listWidget_1listWidget_2,那么您可以使用valueChanged/setValue信号/插槽对来连接两个listwidgets的垂直滑块,确实,我没有发现任何信号在这个"双向"连接中重新反弹的问题,因为最终两个值将是相同的,我认为不会发出更多的信号, 因此,您可以设置这样的足够连接:

    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);

如果信号反弹无论如何都应该被阻止,那么可以通过添加单个slot来处理两个小部件的滚动并将两个小部件连接到该插槽来调整模型:

    connect(this->ui->listWidget_1->verticalScrollBar(),&QScrollBar::valueChanged
 , this, &MainWindow::handleScroll);
    connect(this->ui->listWidget_2->verticalScrollBar(),&QScrollBar::valueChanged
 , this, &MainWindow::handleScroll);

插槽逻辑可以是:

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);
    }
}

您必须使用来自 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"

相关内容

  • 没有找到相关文章