Python – How to make a synchronous scroll bar in PyQt4’s QListWidget

How to make a synchronous scroll bar in PyQt4’s QListWidget… here is a solution to the problem.

How to make a synchronous scroll bar in PyQt4’s QListWidget

I

have two list widgets and I want to sync the scroll bars of both lists. I’m new to PyQt4, so I don’t know what to do.

My code is as follows

Code:

from PyQt4 import QtGui,QtCore
import sys

def window():
    app = QtGui.QApplication(sys.argv)
    win = QtGui.QWidget()
    main_horizontal = QtGui.QHBoxLayout()
    verti_1 = QtGui.QVBoxLayout()
    verti_2 = QtGui.QVBoxLayout()
    list1 = QtGui.QListWidget()
    for i in range(20):
        list1.addItem(str(i))

list2 = QtGui.QListWidget()
    for i in range(20):
        list2.addItem("name" + str(i))

verti_1.addWidget(list1)
    verti_2.addWidget(list2)

main_horizontal.addLayout(verti_1)
    main_horizontal.addLayout(verti_2)
    win.setLayout(main_horizontal)
    win.resize(400,200)
    win.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    window()

Output:
enter image description here

Expected output

I want to have these two scrollbars in sync

Solution

The solution is to connect the valueChanged signal of verticalScrollBar() to the slot where another verticalScrollBar() moves, but this can create an infinite loop, so you have to use blockSignals(). to avoid it as follows:

import sys

from functools import partial

from PyQt4 import QtGui,QtCore

def move_scrollbar(vs, value):
    vs.blockSignals(True)
    vs.setValue(value)
    vs.blockSignals(False)

def window():
    app = QtGui.QApplication(sys.argv)
    win = QtGui.QWidget()
    main_horizontal = QtGui.QHBoxLayout()
    verti_1 = QtGui.QVBoxLayout()
    verti_2 = QtGui.QVBoxLayout()
    list1 = QtGui.QListWidget()
    for i in range(20):
        list1.addItem(str(i))

list2 = QtGui.QListWidget()
    for i in range(20):
        list2.addItem("name" + str(i))

verti_1.addWidget(list1)
    verti_2.addWidget(list2)

vs1 = list1.verticalScrollBar()
    vs2 = list2.verticalScrollBar()

vs1.valueChanged.connect(partial(move_scrollbar, vs2))
    vs2.valueChanged.connect(partial(move_scrollbar, vs1))

main_horizontal.addLayout(verti_1)
    main_horizontal.addLayout(verti_2)
    win.setLayout(main_horizontal)
    win.resize(400,200)
    win.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    window()

Related Problems and Solutions