I have a QTableView that uses QItemDelegate and QAbstractTableModel. A row contains a QPushButton, QCheckBox, QCombobox and QTimeEdit. My issue is that text appears behind the widgets. When a cell containing the QPushButton and QCheckBox are selected and then deselected true or false appears behind the widget. The text given for QCombobox and QTimeEdit are also visible behind the widgets.
Minimal example:
import sys
from PySide2.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton, QItemDelegate, QTimeEdit, \
QCheckBox, QComboBox, QTableView
from PySide2.QtCore import QAbstractTableModel, Qt, QTime
from PySide2.QtGui import QIcon
class Delegate(QItemDelegate):
def __init__(self):
QItemDelegate.__init__(self)
self.type_items = ["Job", "Activity"]
def createEditor(self, parent, option, index):
# CHECKBOX, COMBOBOX, LINEEDIT, TIMEDIT
if index.column() == 0:
pushButton = QPushButton(parent)
# icon = QIcon("Images/cross.png")
# pushButton.setIcon(icon)
return pushButton
elif index.column() == 1:
checkBox = QCheckBox(parent)
return checkBox
elif index.column() == 2:
comboBox = QComboBox(parent)
for text in self.type_items:
comboBox.addItem(text, (index.row(), index.column()))
return comboBox
elif index.column() == 3:
timeEdit = QTimeEdit(parent)
timeEdit.setDisplayFormat('HH:mm')
return timeEdit
return super().createEditor(parent, option, index)
class TableModel(QAbstractTableModel):
def __init__(self, data):
super(TableModel, self).__init__()
self._data = data
def data(self, index, role):
if role in (Qt.DisplayRole, Qt.EditRole):
return self._data[index.row()][index.column()]
def rowCount(self, index=None):
return len(self._data)
def columnCount(self, index=None):
return len(self._data[0])
def flags(self, index):
return super().flags(index) | Qt.ItemIsEditable
def setData(self, index, value, role=Qt.EditRole):
if role == Qt.EditRole:
self._data[index.row()][index.column()] = value
self.dataChanged.emit(index, index)
return True
return False
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
# PARENT WIDGET
localWidget = QWidget()
self.table = QTableView(localWidget)
data = [["", Qt.CheckState.Checked, "Job", QTime(2, 1)], ["", Qt.CheckState.Unchecked, "Activity", QTime(3, 0)]]
self.model = TableModel(data)
self.table.setModel(self.model)
self.table.setItemDelegate(Delegate())
# VERTICAL LAYOUT
layout_v = QVBoxLayout()
layout_v.addWidget(self.table)
localWidget.setLayout(layout_v)
for row in range(self.model.rowCount()):
for column in range(self.model.columnCount()):
index = self.model.index(row, column)
self.table.openPersistentEditor(index)
col_widths = [40, 40, 90, 65]
for col in range(self.model.columnCount()):
self.table.setColumnWidth(col, col_widths[col])
self.setCentralWidget(localWidget)
self.show()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
How can I stop the text showing behind the widgets?
A possible solution is that the text that is painted is an empty string.
class Delegate(QItemDelegate):
def __init__(self):
QItemDelegate.__init__(self)
self.type_items = ["Job", "Activity"]
def drawDisplay(self, painter, option, rect, text):
super().drawDisplay(painter, option, rect, "")
def createEditor(self, parent, option, index):
# ...