Получите значения QTableWidget для отображения в другом QDialog

#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)