#python #qt #pyqt5 #python-3.7
Вопрос:
Я создаю плагин для QGIS 3.16, используя PyQt5. В настоящее время у меня есть три Qdialog, созданных с помощью Qt Designer. Один основной диалог и два всплывающих окна. Первое всплывающее окно содержит пару строк и двойных пробелов, которые при заполнении передают данные в QTableWidget в главном диалоговом окне. Это работает нормально, но данные добавляются после вызова основного диалогового окна, что, как я полагаю, отчасти является причиной проблемы.
Второе всплывающее окно содержит несколько динамически добавляемых комбинаций. Я хочу заполнить эти выпадающие списки списком элементов из строк ранее упомянутого QTableWidget. Однако, когда я пытаюсь создать список для заполнения выпадающего списка, он остается пустым. Как я могу обратиться к главному диалоговому окну после заполнения QTableWidget, чтобы список был правильно заполнен?
Соответствующий фрагмент из основного диалогового класса (обратите внимание, что база для кода была создана с помощью QGIS plugin builder 3)
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'dialog_base.ui'))
FORM_CLASS_TAXA, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'dialog_popup_taxa.ui'))
FORM_CLASS_VEGCOM, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'dialog_popup_vegcom.ui'))
class MainDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super(MainDialog, self).__init__(parent)
self.setupUi(self)
self.addNew_Taxa.clicked.connect(self.addNewTaxon)
self.addNew_VegCom.clicked.connect(self.addNewVegCom)
def addNewTaxon(self):
""" Adds a new pollen taxon to the list of taxa by opening a pop-up in which the taxon short name can be given"""
self.taxonPopup = AddTaxonPopup()
self.taxonPopup.show()
result = self.taxonPopup.exec_()
# runs when apply is clicked on the add new taxon popup
if result:
# Get filled in values
taxonShortName = self.taxonPopup.lineEdit_taxonShortName.text()
# Check if entry is valid and add to table
if taxonShortName:
rowCount = self.tableWidget_Taxa.rowCount()
self.tableWidget_Taxa.setRowCount(rowCount 1)
self.tableWidget_Taxa.setItem(rowCount, 0, QTableWidgetItem(taxonShortName))
else:
pass
def addNewVegCom(self):
""" Adds a new vegetation community to the list of communities by opening a pop-up in which a list of species
and their percentages, as well as a new community name can be given"""
self.vegComPopup = AddVegComPopup()
self.vegComPopup.show()
#add entries to table (not yet implemented)
result = self.vegComPopup.exec_()
if result:
pass
код для всплывающего окна 1 (поскольку ничего не должно создаваться динамически, это просто относится к файлу .ui, содержащему одну строку)
class AddTaxonPopup (QtWidgets.QDialog, FORM_CLASS_TAXA):
def __init__(self, parent=None):
"""Popup Constructor."""
super(AddTaxonPopup, self).__init__(parent)
self.setupUi(self)
код для всплывающего окна 2 (немного беспорядок, потому что он частично создан в файле .ui и частично здесь, в коде)
class AddVegComPopup (QtWidgets.QDialog, FORM_CLASS_VEGCOM):
def __init__(self, parent=None):
"""Popup Constructor."""
super(AddVegComPopup, self).__init__(parent)
self.setupUi(self)
#events
self.pushButton_vegComAddSpecies.clicked.connect(self.addVegComTaxonRow)
#class variable for keeping count of the number of taxa
self.previous = 0
#add gridlayout to scrollarea
self.frameforscrolling = QFrame(self.scrollArea)
self.frameforscrolling.setLayout(self.gridLayout)
self.scrollArea.setWidget(self.frameforscrolling)
#set locations of original .ui widgets in grid (because I couldn't get the grid to behave in Qt designer)
self.gridLayout.addWidget(self.label_Title, 0, 0, 1, 4)
self.gridLayout.addWidget(self.label_Name, 1, 0)
self.gridLayout.addWidget(self.buttonBox_2, 2, 1, 1, 3)
def addVegComTaxonRow(self):
""" Adds a new comboBox and doubleSpinBox to be able to add a new taxon to a vegetation community"""
#get location of start OR previous taxon comboBox
label = QLabel('Taxon ' str(int((self.previous * 0.5) 1)), self)
self.comboBox = QComboBox()
doubleSpin = QDoubleSpinBox()
# insert the new widgets
self.gridLayout.addWidget(label, self.previous 2, 0, 1, 4)
self.gridLayout.addWidget(self.comboBox, self.previous 3, 0, 1, 3)
self.gridLayout.addWidget(doubleSpin, self.previous 3, 3, 1, 2)
self.gridLayout.addWidget(self.buttonBox_2, self.previous 4, 0, 1, 4)
self.previous = 2
# Fill the comboBox HERE LIES THE PROBLEM
self.taxonlist = []
self.mainDialog = MainDialog()
for taxon in range(self.mainDialog.tableWidget_Taxa.rowCount()):
self.taxonlist.append(self.mainDialog.tableWidget_Taxa.item(taxon, 0).text())
print(self.taxonlist)
self.comboBox.addItems(self.taxonlist)
Ответ №1:
Проблема в том, что AddVegComPopup.addVegComTaxonRow
вы создаете новый экземпляр MainDialog
и извлекаете список элементов из этого нового (скрытого) виджета, а не из существующего диалогового окна, отображаемого на экране. Один из способов обойти это-предоставить список элементов в AddVegComPopup
диалоговое окно в момент его инициализации MainDialog.addNewVegCom
и назначить этот список переменной экземпляра AddVegComPopup
, чтобы вы могли обращаться к нему каждый раз, когда создаете новое выпадающее окно. Для этого MainDialog.addNewVegCom
нужно было бы изменить что-то вроде этого:
def addNewVegCom(self):
""" Adds a new vegetation community to the list of communities by opening a pop-up in which a list of species
and their percentages, as well as a new community name can be given"""
table = self.tableWidget_Taxa
item_lst = [table.item(row, 0).text() for row in range(table.rowCount())]
self.vegComPopup = AddVegComPopup(item_lst)
result = self.vegComPopup.exec_()
if result:
pass
И AddVegComPopup
его необходимо будет обновить в соответствии с
class AddVegComPopup (QtWidgets.QDialog):
def __init__(self, taxonlist, parent=None): # note extra input parameter
"""Popup Constructor."""
... as before ...
self.taxonlist = taxonlist
....
def addVegComTaxonRow(self):
""" Adds a new comboBox and doubleSpinBox to be able to add a new taxon to a vegetation community"""
# this is the same as before
label = QLabel('Taxon ' str(int((self.previous * 0.5) 1)), self)
self.comboBox = QComboBox()
doubleSpin = QDoubleSpinBox()
# insert the new widgets
self.gridLayout.addWidget(label, self.previous 2, 0, 1, 4)
self.gridLayout.addWidget(self.comboBox, self.previous 3, 0, 1, 3)
self.gridLayout.addWidget(doubleSpin, self.previous 3, 3, 1, 2)
self.gridLayout.addWidget(self.buttonBox_2, self.previous 4, 0, 1, 4)
self.previous = 2
# use predefined list
self.comboBox.addItems(self.taxonlist)