Search code examples
pythonpyside

How to add multiple QPushButtons to a QTableView?


I have a QTableView to which I want to set a QPushButton for every row. I am doing this as follows within my class derived from QWidget following an example found here:

 for index in range(number_rows):
        btn_sell = QPushButton("Edit", self)
        btn_sell.clicked.connect(self.button_edit)
        table_view.setIndexWidget(table_view.model().index(index, 4), btn_sell)

If the table is drawn and I click on one of the QPushButton the method self.button_edit is called - but which one? It does not seem that an 'event' of any sort is given to self.button_edit, so how can I find the row-index of the QPushButton that was clicked within the button_edit method?

Maybe there is a different way altogether to add a button to each row of a table?


Solution

  • Your event handler will look similar to this:

    def handleButtonClicked(self):
        button = QtGui.qApp.focusWidget()
        # or button = self.sender()
        index = self.table.indexAt(button.pos())
        if index.isValid():
            print(index.row(), index.column())
    

    This uses the indexAt function to get the button's position.

    For clarity, my script looks like this:

    class MainWindow(QtGui.QMainWindow):
        def __init__(self, parent=None):
            QtGui.QMainWindow.__init__(self,parent)
            self.table = QtGui.QTableWidget()
            self.table.setColumnCount(3)
            self.setCentralWidget(self.table)
            data1 = ['row1','row2','row3','row4']
            data2 = ['1','2.0','3.00000001','3.9999999']
    
            self.table.setRowCount(4)
    
            for index in range(4):
                item1 = QtGui.QTableWidgetItem(data1[index])
                self.table.setItem(index,0,item1)
                item2 = QtGui.QTableWidgetItem(data2[index])
                self.table.setItem(index,1,item2)
                self.btn_sell = QtGui.QPushButton('Edit')
                self.btn_sell.clicked.connect(self.handleButtonClicked)
                self.table.setCellWidget(index,2,self.btn_sell)
    
        def handleButtonClicked(self):
            button = QtGui.qApp.focusWidget()
            # or button = self.sender()
            index = self.table.indexAt(button.pos())
            if index.isValid():
                print(index.row(), index.column())
    

    Which will produce a small GUI like this:

    small gui

    When the Edit buttons are clicked, it prints, to the console:

    (0, 2)
    (1, 2)
    (2, 2)
    (3, 2)
    

    The first element is your row index, the second is your column (remember it is 0 based, which is why it shows 2, not 3 - despite the column headers).