Add/Remove 布局包含多个小部件 pyqt
Add/Remove layout containing multiple widgets pyqt
我正在尝试制作一个允许 addition/removal 多个 QtWidget 的图形用户界面。用户选择一个文件,然后可以选择在它旁边的行编辑中添加注释。到目前为止,在该站点上的快速搜索为我提供了以下代码,这些代码允许我添加行小部件。
import os
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
class Additional(QtWidgets.QMainWindow):
def __init__(self):
super(Additional, self).__init__()
self.addButton = QtWidgets.QPushButton(' + ')
self.delButton = QtWidgets.QPushButton(' - ')
self.acceptButton = QtWidgets.QPushButton('Accept')
self.cancelButton = QtWidgets.QPushButton('Cancel')
self.addButton.clicked.connect(self.addWidget)
self.delButton.clicked.connect(self.delWidget)
self.acceptButton.clicked.connect(self.acceptValues)
self.cancelButton.clicked.connect(self.cancel)
self.scrollLayout = QtWidgets.QFormLayout()
self.scrollWidget = QtWidgets.QWidget()
self.scrollWidget.setLayout(self.scrollLayout)
self.scrollArea = QtWidgets.QScrollArea()
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setWidget(self.scrollWidget)
self.button_layout = QtWidgets.QVBoxLayout()
self.mainLayout = QtWidgets.QHBoxLayout()
self.button_layout.addWidget(self.addButton)
self.button_layout.addWidget(self.delButton)
self.button_layout.addWidget(self.acceptButton)
self.button_layout.addWidget(self.cancelButton)
self.mainLayout.addLayout(self.button_layout)
self.mainLayout.addWidget(self.scrollArea)
self.centralWidget = QtWidgets.QWidget()
self.centralWidget.setLayout(self.mainLayout)
self.setCentralWidget(self.centralWidget)
self.resize(800, 200)
self.setFixedSize(self.size())
self.show()
def addWidget(self):
self.scrollLayout.addRow(AddRow())
def delWidget(self):
# Would this call another class to remove the row? If so, how?
pass
def acceptValues(self):
# Would I count the widgets in the 'scroll' area and get the data from that?
pass
def cancel(self):
QtCore.QCoreApplication.instance().quit()
# BTW, is this the right way to close the window/instance?
class AddRow(QtWidgets.QWidget):
def __init__( self, parent=None):
super(AddRow, self).__init__(parent)
self.button = QtWidgets.QPushButton('Select file')
self.label = QtWidgets.QLabel('Selection will go here')
self.lineedit = QtWidgets.QLineEdit()
self.lineedit.setPlaceholderText("Rename (optional)...")
# Would I add the button callback here?
layout = QtWidgets.QHBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.label)
layout.addWidget(self.lineedit)
self.setLayout(layout)
app = QtWidgets.QApplication(sys.argv)
myApp = Additional()
app.exec_()
我在想办法:
- 如何删除添加的最后一行。
- 如何将动作分配给按钮(这在 'AddRow'
class喜欢
self.buttton.clicked.callback(self.selectfile)
- 如何从行中收集数据(即,在 'accept' 之后
单击)
欢迎提出任何想法!
在指向解决方案之前,我只是将 AddRow class 的名称更改为 RowWidget,因为 class 不应指示操作。
class RowWidget(QtWidgets.QWidget):
def __init__( self, parent=None):
super(RowWidget, self).__init__(parent)
...
如何删除添加的最后一行?
由于您使用的是 QFormLayout 并假设您使用的是 PyQt5>=5.8 版本,因此您可以使用 removeRow() 方法:
@QtCore.pyqtSlot()
def delWidget(self):
if self.scrollLayout.rowCount() > 0:
self.scrollLayout.removeRow(self.scrollLayout.rowCount()-1)
如何将动作分配给按钮(这在 'AddRow' class likeself.buttton.clicked.callback(self.selectfile)?
您的应用程序的每个部分都必须是独立的,因此您 select 文件的插槽必须只是 RowWidget 的一部分,并且 RowWidget 必须有一个方法 returns 该值:
class RowWidget(QtWidgets.QWidget):
def __init__( self, parent=None):
super(RowWidget, self).__init__(parent)
self.button = QtWidgets.QPushButton('Select file')
self.label = QtWidgets.QLabel('Selection will go here')
self.lineedit = QtWidgets.QLineEdit()
self.lineedit.setPlaceholderText("Rename (optional)...")
self.button.clicked.connect(self.on_select_file)
layout = QtWidgets.QHBoxLayout(self)
layout.addWidget(self.button)
layout.addWidget(self.label)
layout.addWidget(self.lineedit)
@QtCore.pyqtSlot()
def on_select_file(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Open File")
if filename:
self.lineedit.setText(filename)
def get_filename(self):
return self.lineedit.text()
如何从行中收集数据(即,在 'accept' 被点击后)?
附加到布局的小部件是已添加布局的小部件的children,可以通过parentWidget(), having that parent we can obtain their children through findChildren():
获取该小部件
@QtCore.pyqtSlot()
def acceptValues(self):
l_values = []
for w in self.scrollLayout.parentWidget().findChildren(RowWidget):
l_values.append(w.get_filename())
print(l_values)
如果 parentWidget()
有属于 RowWidget
的其他 children。
之前的方法可能会失败
另一个不会失败的选项是遍历 QLayoutItem
s:
@QtCore.pyqtSlot()
def acceptValues(self):
l_values = []
for i in range(self.scrollLayout.rowCount()):
layout_item = self.scrollLayout.itemAt(i)
if isinstance(layout_item.widget(), RowWidget):
l_values.append(layout_item.widget().get_filename())
print(l_values)
我正在尝试制作一个允许 addition/removal 多个 QtWidget 的图形用户界面。用户选择一个文件,然后可以选择在它旁边的行编辑中添加注释。到目前为止,在该站点上的快速搜索为我提供了以下代码,这些代码允许我添加行小部件。
import os
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
class Additional(QtWidgets.QMainWindow):
def __init__(self):
super(Additional, self).__init__()
self.addButton = QtWidgets.QPushButton(' + ')
self.delButton = QtWidgets.QPushButton(' - ')
self.acceptButton = QtWidgets.QPushButton('Accept')
self.cancelButton = QtWidgets.QPushButton('Cancel')
self.addButton.clicked.connect(self.addWidget)
self.delButton.clicked.connect(self.delWidget)
self.acceptButton.clicked.connect(self.acceptValues)
self.cancelButton.clicked.connect(self.cancel)
self.scrollLayout = QtWidgets.QFormLayout()
self.scrollWidget = QtWidgets.QWidget()
self.scrollWidget.setLayout(self.scrollLayout)
self.scrollArea = QtWidgets.QScrollArea()
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setWidget(self.scrollWidget)
self.button_layout = QtWidgets.QVBoxLayout()
self.mainLayout = QtWidgets.QHBoxLayout()
self.button_layout.addWidget(self.addButton)
self.button_layout.addWidget(self.delButton)
self.button_layout.addWidget(self.acceptButton)
self.button_layout.addWidget(self.cancelButton)
self.mainLayout.addLayout(self.button_layout)
self.mainLayout.addWidget(self.scrollArea)
self.centralWidget = QtWidgets.QWidget()
self.centralWidget.setLayout(self.mainLayout)
self.setCentralWidget(self.centralWidget)
self.resize(800, 200)
self.setFixedSize(self.size())
self.show()
def addWidget(self):
self.scrollLayout.addRow(AddRow())
def delWidget(self):
# Would this call another class to remove the row? If so, how?
pass
def acceptValues(self):
# Would I count the widgets in the 'scroll' area and get the data from that?
pass
def cancel(self):
QtCore.QCoreApplication.instance().quit()
# BTW, is this the right way to close the window/instance?
class AddRow(QtWidgets.QWidget):
def __init__( self, parent=None):
super(AddRow, self).__init__(parent)
self.button = QtWidgets.QPushButton('Select file')
self.label = QtWidgets.QLabel('Selection will go here')
self.lineedit = QtWidgets.QLineEdit()
self.lineedit.setPlaceholderText("Rename (optional)...")
# Would I add the button callback here?
layout = QtWidgets.QHBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.label)
layout.addWidget(self.lineedit)
self.setLayout(layout)
app = QtWidgets.QApplication(sys.argv)
myApp = Additional()
app.exec_()
我在想办法:
- 如何删除添加的最后一行。
- 如何将动作分配给按钮(这在 'AddRow'
class喜欢
self.buttton.clicked.callback(self.selectfile)
- 如何从行中收集数据(即,在 'accept' 之后
单击)
欢迎提出任何想法!
在指向解决方案之前,我只是将 AddRow class 的名称更改为 RowWidget,因为 class 不应指示操作。
class RowWidget(QtWidgets.QWidget):
def __init__( self, parent=None):
super(RowWidget, self).__init__(parent)
...
如何删除添加的最后一行?
由于您使用的是 QFormLayout 并假设您使用的是 PyQt5>=5.8 版本,因此您可以使用 removeRow() 方法:
@QtCore.pyqtSlot()
def delWidget(self):
if self.scrollLayout.rowCount() > 0:
self.scrollLayout.removeRow(self.scrollLayout.rowCount()-1)
如何将动作分配给按钮(这在 'AddRow' class likeself.buttton.clicked.callback(self.selectfile)?
您的应用程序的每个部分都必须是独立的,因此您 select 文件的插槽必须只是 RowWidget 的一部分,并且 RowWidget 必须有一个方法 returns 该值:
class RowWidget(QtWidgets.QWidget):
def __init__( self, parent=None):
super(RowWidget, self).__init__(parent)
self.button = QtWidgets.QPushButton('Select file')
self.label = QtWidgets.QLabel('Selection will go here')
self.lineedit = QtWidgets.QLineEdit()
self.lineedit.setPlaceholderText("Rename (optional)...")
self.button.clicked.connect(self.on_select_file)
layout = QtWidgets.QHBoxLayout(self)
layout.addWidget(self.button)
layout.addWidget(self.label)
layout.addWidget(self.lineedit)
@QtCore.pyqtSlot()
def on_select_file(self):
filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Open File")
if filename:
self.lineedit.setText(filename)
def get_filename(self):
return self.lineedit.text()
如何从行中收集数据(即,在 'accept' 被点击后)?
附加到布局的小部件是已添加布局的小部件的children,可以通过parentWidget(), having that parent we can obtain their children through findChildren():
获取该小部件@QtCore.pyqtSlot()
def acceptValues(self):
l_values = []
for w in self.scrollLayout.parentWidget().findChildren(RowWidget):
l_values.append(w.get_filename())
print(l_values)
如果 parentWidget()
有属于 RowWidget
的其他 children。
另一个不会失败的选项是遍历 QLayoutItem
s:
@QtCore.pyqtSlot()
def acceptValues(self):
l_values = []
for i in range(self.scrollLayout.rowCount()):
layout_item = self.scrollLayout.itemAt(i)
if isinstance(layout_item.widget(), RowWidget):
l_values.append(layout_item.widget().get_filename())
print(l_values)