I have created a working PushButton Delegate for a QTableView. When the button is pressed, it will emit a buttonClicked signal (and also print to show that it is working.
I have set the pushbutton delegate as the item delegate for the column 1 (see tableview.setItemDelegateForColumn(1, delegate) near the end.
Where I am stuck is that I want to know how one can go about connecting to the pushButton emit signal. As a starter, I can loop through my rows/columns and find the each element in the tableView (which you can see in the example at the end), so I'm thinking this might be the point at which I can make the connection. However, I'm not sure how to do it. Can it be done at the column level?
Any help would be appreciated.
# python 3.6
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (QApplication, QStyleOptionButton, QTableView, QStyledItemDelegate, QStyle)
from PyQt5.QtCore import QModelIndex
class PushButtonDelegate(QStyledItemDelegate):
    buttonClicked = QtCore.pyqtSignal(int, int)
    def __init__(self, parent = None):
    super().__init__(parent)
    self._pressed = None
    self._buttonTxt = 'Press Me'
    def paint(self, painter, option, index):
        painter.save()
        opt = QStyleOptionButton()
        opt.text = self._buttonTxt
        opt.rect = option.rect
        opt.palette = option.palette
        if self._pressed and self._pressed == (index.row(), index.column()):
            opt.state = QStyle.State_Enabled | QStyle.State_Sunken
        else:
            opt.state = QStyle.State_Enabled | QStyle.State_Raised
        QtWidgets.QApplication.style().drawControl(QStyle.CE_PushButton, opt, painter)
        painter.restore()
    def editorEvent(self, event, model, option, index):
        if event.type() == QtCore.QEvent.MouseButtonPress:
            # store the position that is clicked
            self._pressed = (index.row(), index.column())
            return True
        elif event.type() == QtCore.QEvent.MouseButtonRelease:
            if self._pressed == (index.row(), index.column()):
                print("Button pressed at {} {}".format(index.row(), index.column()))
                self.buttonClicked.emit(*self._pressed)
            self._pressed = None
            return True
        return False
    def createEditor(self, parent, option, index):
        """ Disable the createEditor or you'll lose your button on a double-click """
        return None
    def setEditorData(self, item, index):
        """ We don't change what's in the button so disable this event also """
        return None
def callBack_test(row, col):
    print("CallbackTest called with {} {}".format(row, col))
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    rows = 4
    cols = 2
    delegate_col = 1
    # Create an table view with a bunch of rows and columsn
    model = QtGui.QStandardItemModel(rows, cols)
    tableView = QTableView()
    tableView.setWindowTitle("Pushbutton Delegate example")
    tableView.setModel(model)
    # We are setting column 1 to use the push button widget
    delegate = PushButtonDelegate(None)
    delegate.buttonClicked.connect(callBack_test)  #<-- This is the answer
    tableView.setItemDelegateForColumn(delegate_col, delegate)
    # Now lets loop through our button delegates and connect to the signal?
    for row in range(rows):
        index = model.index(row, delegate_col, QModelIndex())
        model.setData(index, 1)
        # Is it possible to connect to the pushbutton signal here?
    tableView.show()
    sys.exit(app.exec_())
                One delegate instance emits the buttonClicked signal for all columns, so you simply need to do:
delegate = PushButtonDelegate(None)
delegate.connect(slot)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With