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))
我用 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))