Search code examples
pythonpyqtpyqt4signals-slotsqtablewidget

PyQt: Get QTableWidget cell-widget row/column values


I have a QTablWidget with the following properties:

        mytable.setEditTriggers(QtGui.QTableWidget.NoEditTriggers)
        mytable.setSelectionBehavior(QtGui.QTableWidget.SelectRows)
        mytable.setSelectionMode(QtGui.QTableWidget.SingleSelection)
        mytable.horizontalHeader().setStretchLastSection(True)
        mytable.verticalHeader().hide()

On each row of my table, I have a QPushButton set at a CellWidget like this:

enter image description here

Is there any way to get the Row number of table that the QPushButton is in once user press on any of the button?

For example, if user click on the QPushButton on the row 2 of the table, it returns a value of 2.

EDIT 2

According to one of the answer, i have updated the code to this: but I am still not getting anything. Where have i gone wrong? I tried to print out the output of self.table.itemAt(button.pos()) and i am getting None .

from PyQt4 import QtGui,QtCore
import sys

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 = ['orange','apple','banana','lemon']
        data2 = ['3','4','5.5','2']

        self.table.setRowCount(4)

        for i in range(4):
            item1 = QtGui.QTableWidgetItem(data1[i])
            self.table.setItem(i,0,item1)
            item2 = QtGui.QTableWidgetItem(data2[i])
            self.table.setItem(i,1,item2)
            self.button = QtGui.QPushButton('TEST')
            self.button.clicked.connect(self.handleButtonClicked)
            self.table.setCellWidget(i,2,self.button)

    def handleButtonClicked(self):
        button = self.sender()
        item = self.table.itemAt(button.pos())
        if item is not None:
            print (item.row(),item.column())


def Main():
    app = QtGui.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    app.exec_()

if __name__ == '__main__':
    Main()

Solution

  • If you can get a reference to the button that was clicked, then the indexAt method can be used to get the corresponding model-index:

    button.clicked.connect(self.handleButtonClicked)
    ...        
    
    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())
    

    The reason why the second example in the question returns None with itemAt is because a QTableWidgetItem wasn't set for the cell the button occupies. By contrast, the indexAt method will always return a model-index (which will only be invalid for coordinates in empty areas of the view).