Search code examples
pythonpython-2.7pyqtpyqt4qslider

QSlider with icons


Given a set of images, I'd like to move a QSlider such that every step shows a little thumbnail icon just above it representing one of the images. Any tips or suggestions?


Solution

  • You have to use a QLabel to show the icon and the valueChanged signal of QSlider to make the icon change.

    import sys
    
    from PyQt4.QtCore import pyqtSlot, Qt
    from PyQt4.QtGui import QWidget, QVBoxLayout, QLabel, QSlider, QApplication, QPixmap
    
    
    class Widget(QWidget):
        def __init__(self):
            QWidget.__init__(self)
            self.list_icons = ["icon1.png", "icon2.png", "icon3.png", "icon4.png", "icon5.png", "icon6.png"]
    
            lay = QVBoxLayout(self)
            self.label = QLabel()
            self.label.setAlignment(Qt.AlignHCenter)
            slider = QSlider(Qt.Horizontal)
            lay.addWidget(self.label)
            lay.addWidget(slider)
            slider.setMaximum(len(self.list_icons)-1)
            slider.valueChanged.connect(self.on_change_value)
            self.on_change_value(0)
    
        @pyqtSlot(int)
        def on_change_value(self, value):
            icon = self.list_icons[value]
            self.label.setPixmap(QPixmap(icon))
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())
    

    Update:

    It is not necessary to calculate the position, you should only use Qt Style Sheet.

    import sys
    
    from PyQt4.QtCore import pyqtSlot, Qt
    from PyQt4.QtGui import QWidget, QVBoxLayout, QLabel, QSlider, QApplication, QPixmap
    
    
    class IconSlider(QSlider):
        def __init__(self, icons, *args, **kwargs):
            QSlider.__init__(self, *args, **kwargs)
            self.icons = icons
            self.setMaximum(len(self.icons)-1)
            self.valueChanged.connect(self.on_change_value)
            self.on_change_value(0)
    
        @pyqtSlot(int)
        def on_change_value(self, value):
            icon = self.icons[value]
            self.setStyleSheet('''
                    QSlider::handle:horizontal{{
                        image: url({});
                        margin: -4px 0;
                    }}
                '''.format(icon))
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        w = IconSlider(["icon1.png", "icon2.png", "icon3.png", "icon4.png", "icon5.png", "icon6.png"], Qt.Horizontal)
        w.show()
        sys.exit(app.exec_())
    

    enter image description here

    enter image description here

    enter image description here