【问题标题】:How to synchronize scrolling of the two QListWidgets?如何同步两个 QListWidgets 的滚动?
【发布时间】:2018-03-17 13:56:16
【问题描述】:

有两个QListWidget 具有相同的项目数。怎样才能同步他们的滚动?

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

【问题讨论】:

  • 我的解决方案有效吗?
  • @eyllanesc 需要同步更新。在答案中添加了评论。

标签: c++ qt qt5 qlistwidget


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    你必须使用来自QListWidgetverticalScrollBar()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"
    

    【讨论】:

    • 滚动条是同步的。但图片只在光标下更新。
    • blockSignals() 无法正确同步 - 内容不会滚动。只有valueChanged() 信号断开/连接正常工作。
    • @AlekseyKontsevich 它对我有用,为什么你说它不起作用?,连接和断开连接一点也不优雅。
    • @eyllanesc,正如我所说,在这种情况下,内容不会为我滚动,只有滚动条。
    • @AlekseyKontsevich 好吧,我觉得很奇怪,你用的是我的例子,你用的是什么版本的 Qt?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 2012-05-06
    • 2012-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多