Question

I am new to PySide. In my program, I encountered a problem that when I click one button, it triggers other button later added. Thanks!

    self.addContentButton = QtGui.QPushButton('Add')
    self.addContentButton.clicked.connect(self.addContent)

    def addContent(self):
    '''
        slot to add a row that include a lineedit, combobox, two buttons
    '''
        self.contentTabHBoxWdgt = QtGui.QWidget()

        self.contentName = QtGui.QLineEdit('line edit')

        self.conetentTypeBox = QtGui.QComboBox()
        self.conetentTypeBox.addItem('elem1')
        self.conetentTypeBox.addItem('elem2')

        self.contentSave = QtGui.QPushButton('save',parent = self.contentTabHBoxWdgt)
        self.contentSave.clicked.connect(self.contntSaveAct)

        self.contentDelete = QtGui.QPushButton('delete',parent=self.contentTabHBoxWdgt)
        self.contentDelete.clicked.connect(self.contntDel)

        self.contentTabHBox = QtGui.QHBoxLayout()
        self.contentTabHBox.addWidget(self.contentName)
        self.contentTabHBox.addWidget(self.conetentTypeBox)
        self.contentTabHBox.addWidget(self.contentSave)
        self.contentTabHBox.addWidget(self.contentDelete)

        self.contentTabHBoxWdgt.setLayout(self.contentTabHBox)

        self.contentTabVBox.addWidget(self.contentTabHBoxWdgt)

    def contntDel(self):
    '''
        slot to delete a row 
    '''
        msgBox = QtGui.QMessageBox(QtGui.QMessageBox.Warning, '', 'Be sure to delete')
        okBttn = msgBox.addButton('Yes', QtGui.QMessageBox.AcceptRole)
        noBttn = msgBox.addButton('Cancel', QtGui.QMessageBox.RejectRole)
        ret = msgBox.exec_()
        if msgBox.clickedButton() == okBttn:
            self.contentTabVBox.removeWidget(self.contentDelete.parentWidget());

When I Add one row and click its delete button, it does not work as expected.While I add two or three row , I click one delete button , it remove one row that is not the clicked delete button belong to. How could I achieve this function. Ths!

Was it helpful?

Solution

Your problem is because you aren't really taking advantage of object oriented programming properly.

All rows in your example call the same instance of the method contntDel. This method uses self.contentDelete which always contains a reference to the last row added.

What you need to do is separate out everything related to a row to a new class. When you add a row, create a new instance of this class and pass in the contentTabVBox. That way each row (or instance of the new class you will write) will have it's own delete method.

Without a complete code example, I can't provide a complete solution, but this should give you a rough idea:

class MyRow(object):
    def __init__(self,contentTabVBox, rows):
        self.contentTabVBox = contentTabVBox
        self.my_list_of_rows = rows
        self.addContent()

    def addContent(self):
        # The code for your existing addContent method here

    def contntDel(self):
        # code from your existing contntDel function here
        # also add (if Ok button clicked):
            self.my_list_of_rows.remove(self)

class MyExistingClass(??whatever you have here normally??):
    def __init__(....):
        self.addContentButton = QtGui.QPushButton('Add')
        self.addContentButton.clicked.connect(self.addContent)
        self.my_list_of_rows = []

    def addContent(self):
        my_new_row = MyRow(self.contentTabVBox,self.my_list_of_rows)
        # You mustsave a reference to my_new_row in a list or else it will get garbage collected.
        self.my_list_of_rows.append(my_new_row)

Hope that helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top