dre
dre

Reputation: 183

QTableWidget dynamic rows w/ QComboBox

I have a QTableWidget that I am working on that is supposed to add rows dynamically with comboboxes on certain cells, whenever the user hits a button called Add Cases. I've got the main parts working, but the issue I am having is trying to get the text from the combobox. In the following code, I have a function called def clearcases() as a dummy function for testing. I understand that whenever I am adding a row, the previous rows references are deleted, which is why I can't access them, so I tried creating a list that will keep track of all the combobox objects.

I am getting this error with the current code

Error:

Traceback (most recent call last):
  File "C:\Users\Desktop\VLS.py", line 3888 in clearcases
     print(TotalLift[0].currentText()
RuntimeError: wrapped C/C++ object of type QComboBox has been deleted

TotalLift = []
LiftBox = {}
TotalReed = []
ReedBox = {}
def addcases(self):
    row = self.tableWidget.rowCount()
    self.tableWidget.insertRow(row)
    for x in range(1, 33):
        self.tableWidget.setVerticalHeaderItem(row, QTableWidgetItem('Case ' + chr(ord('A') + row)))
        for i in range(0, 4):
            LiftBox[i] = QtWidgets.QComboBox()
            Lift = ['', 'N', 'M', 'H']
            LiftBox[i].addItems(Lift)
            TotalLift.append(LiftBox[i])
            ReedBox[i] = QtWidgets.QComboBox()
            Reed = ['', 'B', 'C', 'D', 'E', 'O', 'P']
            ReedBox[i].addItems(Reed)
        self.tableWidget.setCellWidget(row, 2, ReedBox[0])
        self.tableWidget.setCellWidget(row, 3, LiftBox[0])
        self.tableWidget.setCellWidget(row, 4, ReedBox[1])
        self.tableWidget.setCellWidget(row, 5, LiftBox[1])
        self.tableWidget.setCellWidget(row, 6, ReedBox[2])
        self.tableWidget.setCellWidget(row, 7, LiftBox[2])
        self.tableWidget.setCellWidget(row, 8, ReedBox[3])
        self.tableWidget.setCellWidget(row, 9, LiftBox[3])
def clearcases(self):
    print(TotalLift[0].currentText())

enter image description here My overall question is, how do I get the text from certain QComboBoxes whenever rows are added?

FYI, the clearcases function is connected to the Clear Case button, so whenever I click the button, I want it to print the 1st rows (Case A) Lift0 text to console.

Running example:

https://drive.google.com/drive/folders/0BzcHlfStubD3cHpUTkttN3h4NDA?usp=sharing

Upvotes: 1

Views: 1527

Answers (1)

eyllanesc
eyllanesc

Reputation: 243887

The problem is mainly caused by the following statement:

for x in range(1, 33):

The previous code entails that codes like the following LiftBox[i] = QtWidgets.QComboBox() is executed repeatedly and therefore the variable is being erased from the memory, obtaining the error message that you mention.

Another bad programming practice is to fill global variables within a class, it is best to make those variables class attributes.

Finally to have a proper order is better not to modify the code generated by Qt Designer, the smart thing is to create a class that handles the logic and to use the design of Qt Designer as shown below:

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi(self)

        self.pushButton.clicked.connect(self.addcases)
        self.pushButton_2.clicked.connect(self.clearcases)

        self.TotalLift = []
        self.LiftBox = {}
        self.TotalReed = []
        self.ReedBox = {}

    def addcases(self):
        row = self.tableWidget.rowCount()
        self.tableWidget.insertRow(row)
        self.tableWidget.setVerticalHeaderItem(row, QTableWidgetItem('Case ' + chr(ord('A') + row)))

        Lift = ['', 'N', 'M', 'H']
        Reed = ['', 'B', 'C', 'D', 'E', 'O', 'P']

        for i in range(4):
            self.LiftBox[i] = QtWidgets.QComboBox(self)
            self.LiftBox[i].addItems(Lift)
            self.TotalLift.append(self.LiftBox[i])
            self.ReedBox[i] = QtWidgets.QComboBox(self)
            self.ReedBox[i].addItems(Reed)
            self.tableWidget.setCellWidget(row, 2*i +2, self.ReedBox[i])
            self.tableWidget.setCellWidget(row, 2*i +3, self.LiftBox[i])

    def clearcases(self):
        print(self.TotalLift[0].currentText())

Upvotes: 1

Related Questions