QT:根据变量(行数)在 UI 中创建多行

QT: Creating multiple rows in a UI dependent on a variable (quantity of rows)

我用 PySide 在 QT 中编写了一个 UI,如下所示:

-Text field- -file browser button-
                 - ok button -

现在我有一个变量,例如i=3 由用户预先定义。我现在想要的是我的 UI 应该动态转换,即

-Text field- -file browser button-
-Text field- -file browser button-
-Text field- -file browser button-
                 - ok button -

所以基本上我得到了我行。当用户输入每个文本字段并单击每个文件浏览器按钮时,我想将所有信息存储在一个包含元组的列表中,即 ((name1,dir1), (name2,dir2), ...)。 到目前为止,这是我的代码:

class SelectFiles(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setWindowTitle('Data Analysis - File selection')
        self.setMinimumWidth(400)
        self.mainlayout = QVBoxLayout()

        # Create the QHBoxLayout that lays out the whole form
        self.layout = QHBoxLayout()

        # Create line for Names
        self.Name1 = QLineEdit(self)
        self.Name1.setPlaceholderText('Name')
        self.layout.addWidget(self.Name1)

        # Create the build button with its caption
        self.build_button = QPushButton('Select File', self)
        # Add it to the button box
        self.layout.addWidget(self.build_button)

        # Connect the button's clicked signal to ReadFileInput
        self.build_button.clicked.connect(self.readfileinput)

        #
        self.mainlayout.addLayout(self.layout)

        # Set the VBox layout as the window's main layout
        self.setLayout(self.mainlayout)

        # Create a horizontal box layout to hold the button
        self.button_box = QHBoxLayout()

        # Add stretch to push the button to the far right
        self.button_box.addStretch(1)

        # Create the build button with its caption
        self.build_buttonOK = QPushButton('Ok', self)

        # Connect the button's clicked signal to ReadInput
        self.build_buttonOK.clicked.connect(self.readnameinputs)

        # Add it to the button box
        self.button_box.addWidget(self.build_buttonOK)

        # Add the button box to the bottom of the main VBox layout
        self.mainlayout.addLayout(self.button_box)

    @Slot()
    def readfileinput(self):
        global fileselect1
        fileselect1 = QFileDialog.getOpenFileName(self)[0]

    @Slot()
    def readnameinputs(self):
        Name = self.Name1.text()

        lists.append((Name, fileselect1))

        qt_app.quit()


    def run(self):
        # Show the form
        self.show()
        # Run the qt application
        qt_app.exec_()

# Classes

qt_app = QApplication(sys.argv)

lists = []

app2 = SelectFiles()
app2.run()

现在,我不是专业程序员,直觉上我会尝试

for j in range(i):
    self.layout + i = QHBoxLayout()
    self.Name + i = QLineEdit(self)

等,当然这在 Python 中是不可能的(-> 使用循环变量定义变量)。现在我不知道如何轻松地做到这一点。有人知道吗?
提前致谢!

您可以使用列表来保存您在 init 函数中初始化的小部件:

self.input_lines = []

我还建议使用 QGridLayout 而不是 QHBoxLayouts,这样您只需要一个布局。 for 循环可能如下所示:

for j in range(i):
    text_field = QLineEdit()
    browser = QPushButton()
    self.input_lines.append((text_field, browser))
    self.grid_layout.addWidget(j, 0, text_field)
    self.grid_layout.addWidget(j, 1, browser)

然后将使用 self.input_lines[index][0] 访问文本字段。

编辑(从评论中添加信息)

要将按钮的 clicked 信号连接到 for 循环中的不同插槽,可以使用 lambda 表达式:

for j in range(i):
    self.input_lines[j][1].clicked.connect(lambda row=j: self.readfileinput(row))