2

I'm using PYQT5 to create a GUI to display sliders, and I want an efficient way to create many sliders of the same type but with different names. Currently, I have to copy paste the same code to make each individual slider, so my code is unnecessarily long.

Here's what it looks like currently for 3 sliders:

class Ui_MainWindow(object):
   def setupUi(self, MainWindow):
    MainWindow.setObjectName("MainWindow")
    self.width = 1120
    self.height = 527
    MainWindow.resize(self.width, self.height)
    self.centralwidget = QtWidgets.QWidget(MainWindow)
    self.centralwidget.setObjectName("centralwidget")
    self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
    self.horizontalLayout.setObjectName("horizontalLayout")
    self.label = QtWidgets.QLabel(self.centralwidget)

    self.verticalSlider1 = QtWidgets.QSlider(self.shape_tab)
    self.shape_minimum = 1
    self.shape_maximum = 2000000
    self.verticalSlider1.setRange(self.shape_minimum, self.shape_maximum)
    self.verticalSlider1.setGeometry(QtCore.QRect(40, 40, 31, 251))
    self.verticalSlider1.setOrientation(QtCore.Qt.Vertical)
    self.verticalSlider1.setMaximum(self.shape_maximum)
    self.verticalSlider1.setObjectName("verticalSlider1")

    self.verticalSlider2 = QtWidgets.QSlider(self.shape_tab)
    self.shape_minimum = 1
    self.shape_maximum = 2000000
    self.verticalSlider2.setRange(self.shape_minimum, self.shape_maximum)
    self.verticalSlider2.setGeometry(QtCore.QRect(80, 40, 31, 251))
    self.verticalSlider2.setOrientation(QtCore.Qt.Vertical)
    self.verticalSlider2.setMaximum(self.shape_maximum)
    self.verticalSlider2.setObjectName("verticalSlider2")

    self.verticalSlider3 = QtWidgets.QSlider(self.shape_tab)
    self.shape_minimum = 1
    self.shape_maximum = 2000000
    self.verticalSlider3.setRange(self.shape_minimum, self.shape_maximum)
    self.verticalSlider3.setGeometry(QtCore.QRect(120, 40, 31, 251))
    self.verticalSlider3.setOrientation(QtCore.Qt.Vertical)
    self.verticalSlider3.setMaximum(self.shape_maximum)
    self.verticalSlider3.setObjectName("verticalSlider3")

I have to create 199 sliders in total, and they have the same properties. They only differ in names and the positioning in the UI (setGeometry(QtCore.QRect()). What's the best way to create this many sliders without just copy and pasting the same code 199 times and changing the name.

I thought of creating a Slider as an class object, but I don't think it works with the UI_MainWindow class. I'm not sure how a for loop would work either. Any thoughts or opinions would be greatly appreciated!

user_13439903
  • 91
  • 1
  • 8

2 Answers2

2

you just have to create a for-loop, and instead of having fixed names you could store them in a list:

...
self.sliders = []
shape_minimum, shape_maximum = 1, 2000000
r = QtCore.QRect(40, 40, 31, 251)

for i in range(199):
    slider = QtWidgets.QSlider(self.shape_tab)
    slider.setRange(shape_minimum, shape_maximum)
    slider.setGeometry(r)
    slider.setOrientation(QtCore.Qt.Vertical)
    slider.setObjectName("verticalSlider{}".format(i+1))
    r.translate(40, 0)
    self.sliders.append(slider)
...

If you still want the sliders to have a name following the pattern you indicate in your code you can use setattr()

shape_minimum, shape_maximum = 1, 2000000
r = QtCore.QRect(40, 40, 31, 251)

for i in range(199):
    slider = QtWidgets.QSlider(self.shape_tab)
    slider.setRange(shape_minimum, shape_maximum)
    slider.setGeometry(r)
    slider.setOrientation(QtCore.Qt.Vertical)
    name = "verticalSlider{}".format(i+1)
    slider.setObjectName(name)
    r.translate(40, 0)
    setattr(self, name, slider)
...
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
1

Try it:

import sys
from PyQt5.QtCore    import Qt
from PyQt5.QtWidgets import (QApplication, QCheckBox, QGridLayout, QGroupBox,
                             QMenu, QPushButton, QRadioButton, QVBoxLayout, 
                             QWidget, QSlider, QLabel, QHBoxLayout, QScrollArea)

class Window(QWidget):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.setWindowTitle("PyQt5 Sliders")
        self.resize(425, 392)        

        grid = QGridLayout()
        scrollWidget = QWidget()
        scrollWidget.setLayout(grid)
        scrollArea = QScrollArea()
        scrollArea.setWidgetResizable(True)
        scrollArea.setWidget(scrollWidget)   
        self.mainLayout = QHBoxLayout()
        self.mainLayout.addWidget(scrollArea)
        self.setLayout(self.mainLayout)

        for row in range(70):
            grid.addWidget(self.createExampleGroup(row, 0), row, 0)
            grid.addWidget(self.createExampleGroup(row, 1), row, 1)
            grid.addWidget(self.createExampleGroup(row, 2), row, 2)

    def createExampleGroup(self, row, column):
        numSlider = row*2+column if row==0 else row*2+column+row
        groupBox = QGroupBox("Slider {}".format(numSlider))

        self.label = QLabel()  
        self.label.setObjectName("label{}".format(numSlider))

        slider = QSlider(Qt.Horizontal)
        name = "slider{}".format(numSlider)
        slider.setObjectName(name) 
        setattr(self, name, self.label) 
        slider.setRange(1, 2000000)
        slider.setFocusPolicy(Qt.StrongFocus)
        slider.setTickPosition(QSlider.TicksBothSides)
        slider.setTickInterval(200000)
        slider.setSingleStep(1)
        slider.valueChanged[int].connect(self.changevalue)

        vbox = QVBoxLayout()
        vbox.addWidget(self.label)
        vbox.addWidget(slider)
        vbox.addStretch(1)
        groupBox.setLayout(vbox)

        return groupBox

    def changevalue(self, value):
        sender = self.sender()
        label  = getattr(self, sender.objectName())
        label.setText("{:>9,}".format(value))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    clock = Window()
    clock.show()
    sys.exit(app.exec_())

enter image description here

S. Nick
  • 12,879
  • 8
  • 25
  • 33