Search code examples
pythonpyqtpyqt4qlistwidget

How to make synchronized Scroll bar in QListWidget in PyQt4


I Have two List Widget and I want to make scroll bar of two list synchronized . I am new to PyQt4 so i don't know how to do that.

My code is given below

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 make these two scroll bar synchronized


Solution

  • The solution is to connect the valueChanged signal of the verticalScrollBar() to a slot where the other verticalScrollBar() moves, but this could generate an infinite loop so to avoid it you must use blockSignals() as shown below:

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