Динамическое добавление виджетов
Имеется форма, которая должна динамически добавлять набор новых виджетов и в последующем данные в этих виджетов будут записаны в json.
По дефолту имеется одна запись категорий с различными типами виджетов:
По нажатию на кнопку добавить аналогичный список виджетов появляется ниже предыдущего и в последующем нужно получить такой вариант:
На сколько я правильно понял нужно реализовать динамическое добавление виджетов, но я не могу прийти к правильной мысли на данный момент.
Пример кода
class UiCategoryWindow(object):
_translate = QtCore.QCoreApplication.translate
def setup_ui(self, form):
form.setObjectName("form")
form.resize(520, 250)
form.setMinimumSize(QtCore.QSize(520, 250))
form.setMaximumSize(QtCore.QSize(520, 1000))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
form.setFont(font)
self.grid_layout_in_form = QtWidgets.QGridLayout(form)
self.grid_layout_in_form.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.grid_layout_in_form.setObjectName("grid_layout_in_form")
self.scroll_area = QtWidgets.QScrollArea(form)
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setAlignment(QtCore.Qt.AlignCenter)
self.scroll_area.setObjectName("scroll_area")
self.scroll_area_widget_contents = QtWidgets.QWidget()
self.scroll_area_widget_contents.setGeometry(QtCore.QRect(0, 0, 494, 156))
self.scroll_area_widget_contents.setObjectName("scroll_area_widget_contents")
self.grid_layout_in_scroll_area = QtWidgets.QGridLayout(self.scroll_area_widget_contents)
self.grid_layout_in_scroll_area.setObjectName("grid_layout_in_scroll_area")
self.line_edit_number = QtWidgets.QLineEdit(self.scroll_area_widget_contents)
self.line_edit_number.setMaximumSize(QtCore.QSize(30, 20))
self.line_edit_number.setText("")
self.line_edit_number.setObjectName("line_edit_number")
self.grid_layout_in_scroll_area.addWidget(self.line_edit_number, 0, 0, 1, 1)
self.line_edit_name = QtWidgets.QLineEdit(self.scroll_area_widget_contents)
self.line_edit_name.setMaximumSize(QtCore.QSize(16777215, 20))
self.line_edit_name.setText("")
self.line_edit_name.setObjectName("line_edit_name")
self.grid_layout_in_scroll_area.addWidget(self.line_edit_name, 0, 1, 1, 1)
self.line_edit_path = QtWidgets.QLineEdit(self.scroll_area_widget_contents)
self.line_edit_path.setMaximumSize(QtCore.QSize(60, 20))
self.line_edit_path.setObjectName("line_edit_path")
self.grid_layout_in_scroll_area.addWidget(self.line_edit_path, 0, 2, 1, 1)
self.label_for_photo = QtWidgets.QLabel(self.scroll_area_widget_contents)
self.label_for_photo.setMaximumSize(QtCore.QSize(40, 24))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_for_photo.setFont(font)
self.label_for_photo.setText("")
self.label_for_photo.setPixmap(QtGui.QPixmap("../../../Downloads/data/categories/8.jpeg"))
self.label_for_photo.setScaledContents(True)
self.label_for_photo.setObjectName("label_for_photo")
self.grid_layout_in_scroll_area.addWidget(self.label_for_photo, 0, 3, 1, 1)
self.push_button_add_photo = QtWidgets.QPushButton(self.scroll_area_widget_contents)
self.push_button_add_photo.setMaximumSize(QtCore.QSize(58, 25))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.push_button_add_photo.setFont(font)
self.push_button_add_photo.setObjectName("push_button_add_photo")
self.grid_layout_in_scroll_area.addWidget(self.push_button_add_photo, 0, 4, 1, 1)
self.push_button_remove_category = QtWidgets.QPushButton(self.scroll_area_widget_contents)
self.push_button_remove_category.setMaximumSize(QtCore.QSize(50, 25))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.push_button_remove_category.setFont(font)
self.push_button_remove_category.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("../MainTable/images/icon/remote.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.push_button_remove_category.setIcon(icon)
self.push_button_remove_category.setObjectName("push_button_remove_category")
self.grid_layout_in_scroll_area.addWidget(self.push_button_remove_category, 0, 5, 1, 1)
self.scroll_area.setWidget(self.scroll_area_widget_contents)
self.grid_layout_in_form.addWidget(self.scroll_area, 1, 0, 1, 1)
self.push_button_save_categories = QtWidgets.QPushButton(form)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.push_button_save_categories.setFont(font)
self.push_button_save_categories.setObjectName("push_button_save_categories")
self.grid_layout_in_form.addWidget(self.push_button_save_categories, 4, 0, 1, 1)
self.push_button_add_category = QtWidgets.QPushButton(form)
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.push_button_add_category.setFont(font)
self.push_button_add_category.setObjectName("push_button_add_category")
self.push_button_add_category.clicked.connect(form.add_new_category)
self.grid_layout_in_form.addWidget(self.push_button_add_category, 0, 0, 1, 1)
self.retranslate_Ui(form)
QtCore.QMetaObject.connectSlotsByName(form)
def retranslate_Ui(self, form):
form.setWindowTitle(self._translate("form", "Добавить категории"))
self.line_edit_number.setPlaceholderText(self._translate("form", "№"))
self.line_edit_name.setPlaceholderText(self._translate("form", "Введите имя категории"))
self.push_button_save_categories.setText(self._translate("form", "Сохранить"))
self.push_button_add_photo.setText(self._translate("form", "Фото"))
self.push_button_add_category.setText(self._translate("form", "Добавить"))
def add_new_category(self):
self.line_edit_number = QtWidgets.QLineEdit(self.scroll_area_widget_contents)
self.line_edit_number.setMaximumSize(QtCore.QSize(30, 20))
self.line_edit_number.setText("")
self.line_edit_number.setObjectName("line_edit_number")
self.line_edit_number.setPlaceholderText(self._translate("form", "№"))
self.grid_layout_in_scroll_area.addWidget(self.line_edit_number, 0, 0, 1, 1)
self.line_edit_name = QtWidgets.QLineEdit(self.scroll_area_widget_contents)
self.line_edit_name.setMaximumSize(QtCore.QSize(16777215, 20))
self.line_edit_name.setText("")
self.line_edit_name.setObjectName("line_edit_name")
self.line_edit_name.setPlaceholderText(self._translate("form", "Введите имя категории"))
self.grid_layout_in_scroll_area.addWidget(self.line_edit_name, 0, 1, 1, 1)
self.line_edit_path = QtWidgets.QLineEdit(self.scroll_area_widget_contents)
self.line_edit_path.setMaximumSize(QtCore.QSize(60, 20))
self.line_edit_path.setObjectName("line_edit_path")
self.grid_layout_in_scroll_area.addWidget(self.line_edit_path, 0, 2, 1, 1)
self.label_for_photo = QtWidgets.QLabel(self.scroll_area_widget_contents)
self.label_for_photo.setMaximumSize(QtCore.QSize(40, 24))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.label_for_photo.setFont(font)
self.label_for_photo.setText("")
self.label_for_photo.setPixmap(QtGui.QPixmap("images/icon/category_plug.png"))
self.label_for_photo.setScaledContents(True)
self.label_for_photo.setObjectName("label_for_photo")
self.grid_layout_in_scroll_area.addWidget(self.label_for_photo, 0, 3, 1, 1)
self.push_button_add_photo = QtWidgets.QPushButton(self.scroll_area_widget_contents)
self.push_button_add_photo.setMaximumSize(QtCore.QSize(58, 25))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.push_button_add_photo.setFont(font)
self.push_button_add_photo.setObjectName("push_button_add_photo")
self.push_button_add_photo.setText(self._translate("form", "Фото"))
self.grid_layout_in_scroll_area.addWidget(self.push_button_add_photo, 0, 4, 1, 1)
self.push_button_remove_category = QtWidgets.QPushButton(self.scroll_area_widget_contents)
self.push_button_remove_category.setMaximumSize(QtCore.QSize(50, 25))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.push_button_remove_category.setFont(font)
self.push_button_remove_category.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("images/icon/remote.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.push_button_remove_category.setIcon(icon)
self.push_button_remove_category.setObjectName("push_button_remove_category")
self.grid_layout_in_scroll_area.addWidget(self.push_button_remove_category, 0, 5, 1, 1)
self.scroll_area.setWidget(self.scroll_area_widget_contents)
self.grid_layout_in_form.addWidget(self.scroll_area, 1, 0, 1, 1)
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Один из вариантов, того что вы хотите сделать, выглядит так:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
class ItemWidget(QWidget):
itemDeleted = pyqtSignal(QListWidgetItem)
def __init__(self, text, item, *args, **kwargs):
super(ItemWidget, self).__init__(*args, **kwargs)
self._item = item # Сохраните ссылку на объект элемента списка
self.layout = QtWidgets.QGridLayout(self)
self.line_edit_number = QtWidgets.QLineEdit()
self.line_edit_number.setMaximumSize(QtCore.QSize(30, 20))
self.line_edit_number.setPlaceholderText("№")
self.layout.addWidget(self.line_edit_number, 0, 0, 1, 1)
self.line_edit_name = QtWidgets.QLineEdit()
self.line_edit_name.setMaximumSize(QtCore.QSize(16777215, 20))
self.line_edit_name.setPlaceholderText("Введите имя категории")
self.layout.addWidget(self.line_edit_name, 0, 1, 1, 1)
self.line_edit_path = QtWidgets.QLineEdit(text)
self.line_edit_path.setMaximumSize(QtCore.QSize(60, 20))
self.layout.addWidget(self.line_edit_path, 0, 2, 1, 1)
self.label_for_photo = QtWidgets.QLabel()
self.label_for_photo.setMaximumSize(QtCore.QSize(40, 24))
self.label_for_photo.setPixmap(QtGui.QPixmap("ball.png"))
self.label_for_photo.setScaledContents(True)
self.layout.addWidget(self.label_for_photo, 0, 3, 1, 1)
self.push_button_add_photo = QtWidgets.QPushButton("Фото")
self.push_button_add_photo.setMaximumSize(QtCore.QSize(58, 25))
self.layout.addWidget(self.push_button_add_photo, 0, 4, 1, 1)
self.push_button_remove_category = QtWidgets.QPushButton(self, clicked=self.doDeleteItem)
self.push_button_remove_category.setMaximumSize(QtCore.QSize(50, 25))
self.push_button_remove_category.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("images/close.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.push_button_remove_category.setIcon(icon)
self.layout.addWidget(self.push_button_remove_category, 0, 5, 1, 1)
def doDeleteItem(self):
self.itemDeleted.emit(self._item)
class Window(QWidget):
def __init__(self):
super().__init__()
self.num = 1
self.listWidget = QListWidget(self)
self.addBtn = QPushButton('Добавить', self, clicked=self.doAdd)
self.saveBtn = QPushButton("Сохранить")
layout = QVBoxLayout(self)
layout.addWidget(self.addBtn)
layout.addWidget(self.listWidget)
layout.addWidget(self.saveBtn)
# Добавить данные
self.testData()
def doDeleteItem(self, item):
# Получить количество строк, соответствующих item
row = self.listWidget.indexFromItem(item).row()
# Удалить item
item = self.listWidget.takeItem(row)
# Удалить widget
self.listWidget.removeItemWidget(item)
del item
def doAdd(self):
self.testData()
def testData(self):
# Создать данные
item = QListWidgetItem(self.listWidget)
item.setSizeHint(QSize(520, 60))
widget = ItemWidget(f'{self.num}', item, self.listWidget)
# Сигнал удаления привязки
widget.itemDeleted.connect(self.doDeleteItem)
self.listWidget.setItemWidget(item, widget)
self.num += 1
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setFont(QtGui.QFont("Arial", 14, QtGui.QFont.Bold))
w = Window()
w.resize(550, 350)
w.show()
sys.exit(app.exec_())


