PYQT5:使用for循环或其他方式创建许多相同类型的QSliders

PYQT5: Using a for loop or something else to create many QSliders of the same type

我正在使用 PYQT5 创建一个 GUI 来显示滑块,我想要一种有效的方法来创建许多相同类型但名称不同的滑块。目前,我必须复制粘贴相同的代码来制作每个单独的滑块,所以我的代码不必要地长。

这是 3 个滑块当前的样子:

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

我总共要创建 199 个滑块,它们具有相同的属性。它们仅在名称和 UI (setGeometry(QtCore.QRect()) 中的位置不同。创建这么多滑块的最佳方法是什么,而不只是复制和粘贴相同的代码 199 次并更改名称.

我想过将 Slider 创建为 class 对象,但我认为它不适用于 UI_MainWindow class。我也不确定 for 循环是如何工作的。任何想法或意见将不胜感激!

您只需创建一个 for 循环,而不是使用固定名称,您可以将它们存储在列表中:

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

如果您仍希望滑块的名称遵循您在代码中指定的模式,您可以使用 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)
...

试一试:

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