fede
26th May 2010, 02:15
Hello,
I am playing around with a custom delegate for a QTableWidget, which just shows a combobox as an editor, stores the value as a number (which is a foreign key to a list), and displays the text corresponding to the item at that value's position in a list. For example: it stores 1 and displays 'one' if the list is ['someitem', 'one'], and stores 4 and displays 'cow' if the list is ['bird', 'horse', 'pig', 'snake', 'cow'].
My problem is I cannot get the appearance of the cells which use the custom delegate 'right' - which in this case would be the same as the default delegate. In particular:
Hovering normal cells with the mouse produces a shadow over the hovered cell. How can I reproduce this effect in my custom delegate? I have tried to find a custom delegate with a working "hover" effect in the examples, without luck. Both the star delegate and the spin box delegate examples have the same problem in the columns affected.
My delegate's painter does not draw using the same cell margins as the default delegate's painter. How should I set these margins in my custom delegate?
Which is the correct way of looking up colors and effects to be used by the custom delegate's paint method so that it mimics the default delegate's style? In particular, the selected item under the default delegate has a sublte "glow" texture in its background,which is not reproduced by my delegate's paint method, which simply uses a solid color as background. I couldn't find this effect in the examples, either, they too seem to use a solid color as background when using custom delegates. (Edited to clarify)
Thanks!
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
class QRelationalDelegate(QtGui.QStyledItemDelegate):
VALUES = ['zero', 'one', 'two', 'three', 'four']
def paint(self, painter, option, index):
value = index.data(QtCore.Qt.DisplayRole).toInt()[0] # integer stored in tablewidget model
text = self.VALUES[value] # text to be displayed
painter.save()
if option.state & QtGui.QStyle.State_Selected: # highligh background if selected
painter.fillRect(option.rect, option.palette.highlight())
painter.drawText(option.rect, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, text)
painter.restore()
def createEditor(self, parent, option, index):
combobox = QtGui.QComboBox(parent)
combobox.addItems(self.VALUES)
combobox.setEditable(True)
return combobox
def setEditorData(self, editor, index):
text = self.VALUES[index.data(QtCore.Qt.DisplayRole).toInt()[0]]
pos = editor.findText(text)
if pos == -1: #text not found, set cell value to first item in VALUES
pos = 0
editor.setCurrentIndex(pos)
def setModelData(self, editor, model, index):
model.setData(index, QtCore.QVariant(editor.currentIndex()))
class myWindow(QtGui.QDialog):
def __init__(self):
QtGui.QDialog.__init__(self)
DATA = [['First row', 1, 1], ['Second Row', 2, 2]]
self.table = QtGui.QTableWidget(self)
self.table.setSortingEnabled(False)
self.table.setRowCount(len(DATA))
self.table.setColumnCount(len(DATA[0]))
self.table.setItemDelegateForColumn(1, QRelationalDelegate(self))
for row in range(len(DATA)):
for col in range(len(DATA[row])):
item = QtGui.QTableWidgetItem(str(DATA[row][col]))
self.table.setItem(row, col, item)
layout = QtGui.QVBoxLayout()
layout.addWidget(self.table)
self.setLayout(layout)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = myWindow()
window.show()
app.exec_()
Attached is a picture the hover effect which works for columns 0 and 2 in my example but not for column 1 which uses the custom delegate.4687
I am playing around with a custom delegate for a QTableWidget, which just shows a combobox as an editor, stores the value as a number (which is a foreign key to a list), and displays the text corresponding to the item at that value's position in a list. For example: it stores 1 and displays 'one' if the list is ['someitem', 'one'], and stores 4 and displays 'cow' if the list is ['bird', 'horse', 'pig', 'snake', 'cow'].
My problem is I cannot get the appearance of the cells which use the custom delegate 'right' - which in this case would be the same as the default delegate. In particular:
Hovering normal cells with the mouse produces a shadow over the hovered cell. How can I reproduce this effect in my custom delegate? I have tried to find a custom delegate with a working "hover" effect in the examples, without luck. Both the star delegate and the spin box delegate examples have the same problem in the columns affected.
My delegate's painter does not draw using the same cell margins as the default delegate's painter. How should I set these margins in my custom delegate?
Which is the correct way of looking up colors and effects to be used by the custom delegate's paint method so that it mimics the default delegate's style? In particular, the selected item under the default delegate has a sublte "glow" texture in its background,which is not reproduced by my delegate's paint method, which simply uses a solid color as background. I couldn't find this effect in the examples, either, they too seem to use a solid color as background when using custom delegates. (Edited to clarify)
Thanks!
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
class QRelationalDelegate(QtGui.QStyledItemDelegate):
VALUES = ['zero', 'one', 'two', 'three', 'four']
def paint(self, painter, option, index):
value = index.data(QtCore.Qt.DisplayRole).toInt()[0] # integer stored in tablewidget model
text = self.VALUES[value] # text to be displayed
painter.save()
if option.state & QtGui.QStyle.State_Selected: # highligh background if selected
painter.fillRect(option.rect, option.palette.highlight())
painter.drawText(option.rect, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, text)
painter.restore()
def createEditor(self, parent, option, index):
combobox = QtGui.QComboBox(parent)
combobox.addItems(self.VALUES)
combobox.setEditable(True)
return combobox
def setEditorData(self, editor, index):
text = self.VALUES[index.data(QtCore.Qt.DisplayRole).toInt()[0]]
pos = editor.findText(text)
if pos == -1: #text not found, set cell value to first item in VALUES
pos = 0
editor.setCurrentIndex(pos)
def setModelData(self, editor, model, index):
model.setData(index, QtCore.QVariant(editor.currentIndex()))
class myWindow(QtGui.QDialog):
def __init__(self):
QtGui.QDialog.__init__(self)
DATA = [['First row', 1, 1], ['Second Row', 2, 2]]
self.table = QtGui.QTableWidget(self)
self.table.setSortingEnabled(False)
self.table.setRowCount(len(DATA))
self.table.setColumnCount(len(DATA[0]))
self.table.setItemDelegateForColumn(1, QRelationalDelegate(self))
for row in range(len(DATA)):
for col in range(len(DATA[row])):
item = QtGui.QTableWidgetItem(str(DATA[row][col]))
self.table.setItem(row, col, item)
layout = QtGui.QVBoxLayout()
layout.addWidget(self.table)
self.setLayout(layout)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = myWindow()
window.show()
app.exec_()
Attached is a picture the hover effect which works for columns 0 and 2 in my example but not for column 1 which uses the custom delegate.4687