[SOLVED] QTableView not scrolling when mouse is at disabled delegate button


Setup description

  • Table in PySide created with
    QMainWindow – > QWidget -> QTableView -> TableModel (QAbstractTableModel) -> array[[]]
  • For second column is created ButtonDelegate(QStyledItemDelegate)

Problem description
If button in delegate is disabled [setEnabled(False)], the scrolling of table is not working when mouse is above the disabled button.


  • When buttons are enabled,everything works well.

  • In my application, I’m enabling/disabling buttons based on the data.

  • Scrolling should work in any case, because otherwise the functionality is not user friendly, when scrolling is not working at one of the table columns – with disabled button(s).

  • I tried few things with eventFilter but nothing worked.

Tested with PySide6 (, Python 3.9, Windows 10, Debian

Possibly the same problem (but no solution listed):

Minimal functioning example:

from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout 
from PySide6.QtWidgets import  QTableView, QWidget, QStyledItemDelegate, QPushButton
from PySide6.QtCore import Qt, QModelIndex, QAbstractTableModel, QItemSelectionModel

class ButtonDelegate(QStyledItemDelegate):
    def __init__(self, parent):
        QStyledItemDelegate.__init__(self, parent)    

    def paint(self, painter, option, index):
        super(ButtonDelegate, self).paint(painter, option, index)

    def createEditor(self, parent, option, index):
        editor = QPushButton("Button", parent)
        return editor

class TableModel(QAbstractTableModel):
    def __init__(self, localData=[[]], parent=None):
        self.modelData = localData

    def headerData(self, section: int, orientation: Qt.Orientation, role: int):
        if role == Qt.DisplayRole:
            if orientation == Qt.Vertical:
                return "Row " + str(section)

    def columnCount(self, parent=None):
        return len(self.modelData[0])

    def rowCount(self, parent=None):
        return len(self.modelData)

    def data(self, index: QModelIndex, role: int):
        if role == Qt.DisplayRole:
            row = index.row()
            col = index.column()
            return self.modelData[row][col]

app = QApplication()

data = [['1', '2'],['1', '2'],['1', '2'],['1', '2'],['1', '2'],['1', '2'],['1', '2'],
    ['1', '2'],['1', '2'],['1', '2'],['1', '2'],['1', '2'],['1', '2'],['1', '2'],
    ['1', '2'],['1', '2'],['1', '2'],['1', '2']]

model = TableModel(data)

tableView = QTableView()
selectionModel = QItemSelectionModel(model)
tableView.setItemDelegateForColumn(1, ButtonDelegate(tableView))

widget = QWidget()
widget.horizontalHeader = tableView.horizontalHeader()
widget.mainLayout = QVBoxLayout()

mainWindow = QMainWindow()
mainWindow.setGeometry(0, 0, 300, 300)



I can reproduce this with PyQt6 so I can confirm that it’s related to Qt6

The difference is that a Wheel event is always accepted on disabled buttons in Qt6 while it’s ignored on Qt5, and it’s related to the special behavior of QAbstractButton for input events. This has been actually considered a wrong behavior for Qt5, so it cannot be considered a bug (see QTBUG-79102 and QTBUG-67032).

The solution is to set the set the event as not accepted in the event filter of the delegate, and return True to propagate the event to the parent:

class ButtonDelegate(QStyledItemDelegate):
    def eventFilter(self, obj, event):
        if event.type() == event.Type.Wheel:
            return True
        return super().eventFilter(obj, event)

Note that opening the editor in the paint function is not a good idea: while the function usually is "ignored" when the editor is already open, any operation that can cause repaint (and, potentially, geometry changes) should never happen inside painting functions.

Answered By – musicamante

Answer Checked By – Gilberto Lyons (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *