Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何同步两个QListWidget的滚动?_C++_Qt_Qt5_Qlistwidget - Fatal编程技术网

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