I’m subclassing QStyledItemDelegate
to show a dropdown QCombobox
in a QTableView
. The delegate detects the dataType from the table’s model, and if the dataType == EnumMeta
, shows a dropdown list of options.
With my current implementation, the dropdown is only displayed after a user double clicks a table cell. The user must then click the dropdown again to show the available options.
Question:
How do I always show the QCombobox
, and have it open immediately when the user clicks the table cell?
Example Code
from enum import EnumMeta
from qgis.PyQt.QtWidgets import (
QStyledItemDelegate,
QWidget,
QComboBox,
)
from qgis.PyQt.QtGui import QPainter
from qgis.PyQt.QtCore import QModelIndex, QSize, QAbstractItemModel, Qt
from .shared_constants import CustomRoles
class BGCustomDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
super(BGCustomDelegate, self).__init__(parent)
self.setParent(parent)
def paint(self, painter: QPainter, option, index: QModelIndex) -> None:
QStyledItemDelegate.paint(self, painter, option, index)
def sizeHint(self, option, index: QModelIndex) -> QSize:
return QStyledItemDelegate.sizeHint(self, option, index)
def createEditor(self, parent: QWidget, option, index: QModelIndex) -> QWidget:
if index.data(CustomRoles.dataType.value) == EnumMeta:
editor = QComboBox(parent)
allowed_values_enum: EnumMeta = index.data(CustomRoles.allowedValues.value)
allowed_values = [e.value for e in allowed_values_enum]
editor.addItems(allowed_values)
return editor
else:
return QStyledItemDelegate.createEditor(self, parent, option, index)
def setEditorData(self, editor: QWidget, index: QModelIndex) -> None:
if index.data(CustomRoles.dataType.value) == EnumMeta:
editor: QComboBox
current_value = index.data(Qt.EditRole)
combo_index = editor.findText(current_value)
if combo_index >= 0:
editor.setCurrentIndex(combo_index)
else:
QStyledItemDelegate.setEditorData(self, editor, index)
def setModelData(
self, editor: QWidget, model: QAbstractItemModel, index: QModelIndex
) -> None:
if index.data(CustomRoles.dataType.value) == EnumMeta:
editor: QComboBox
current_value = editor.currentText()
model.setData(index, current_value, Qt.EditRole)
else:
QStyledItemDelegate.setModelData(self, editor, model, index)