How to make a QCombobox item delegate for its current item? (Qt 4)

QCombobox set A delegate element is not drawn for the current element.

I am trying to create a combo box showing different types of lines (Solid, Dotted, Dash, etc.). I am currently setting a delegate element for its contents to draw / draw a line type instead of displaying names. All line types are drawn correctly, but as soon as I select any line type from combobox, the current index of the combo box displays only the line name and does not draw it. How can I draw the selected line type on the current index with a list?

+4
source share
4 answers

Delegate drawing elements to popup menu:

class LineStyleDelegate(QtGui.QItemDelegate): def __init__(self, object, parent = None): QtGui.QItemDelegate.__init__(self, parent) def paint(self, painter, option, index): data = index.model().data(index, QtCore.Qt.UserRole) if data.isValid() and data.toPyObject() is not None: data = data.toPyObject() painter.save() rect = option.rect rect.adjust(+5, 0, -5, 0) pen = QtGui.QPen() pen.setColor(QtCore.Qt.black) pen.setWidth(3) pen.setStyle(data) painter.setPen(pen) middle = (rect.bottom() + rect.top()) / 2 painter.drawLine(rect.left(), middle, rect.right(), middle) painter.restore() else: QtGui.QItemDelegate.paint(self, painter, option, index) painter.drawLine(rect.left(), middle, rect.right(), middle) painter.restore() else: QtGui.QItemDelegate.paint(self, painter, option, index) 

paintEvent to draw the current item in combo. You can, of course, draw it by hand, but there is an easy way to control the list control yourself (if you want the arrow or smth in the current one):

 def paintEvent(self, e): data = self.itemData(self.currentIndex(), QtCore.Qt.UserRole) if data.isValid() and data.toPyObject() is not None: data = data.toPyObject() p = QtGui.QStylePainter(self) p.setPen(self.palette().color(QtGui.QPalette.Text)) opt = QtGui.QStyleOptionComboBox() self.initStyleOption(opt) p.drawComplexControl(QtGui.QStyle.CC_ComboBox, opt) painter = QtGui.QPainter(self) painter.save() rect = p.style().subElementRect(QtGui.QStyle.SE_ComboBoxFocusRect, opt, self) rect.adjust(+5, 0, -5, 0) pen = QtGui.QPen() pen.setColor(QtCore.Qt.black) pen.setWidth(3) pen.setStyle(data) painter.setPen(pen) middle = (rect.bottom() + rect.top()) / 2 painter.drawLine(rect.left(), middle, rect.right(), middle) painter.restore() else: QtGui.QComboBox.paintEvent(self, e) 
+3
source

I think I came across this problem earlier, having a delegate who correctly displays the line in the drop-down menu, but not in the combo box itself.

The documentation ( http://doc.trolltech.com/4.4/qcombobox.html ) states that:

"The text and icon on the combobox label use the data in the model with Qt :: DisplayRole and Qt :: DecorationRole.

I suspect that an approach that includes a model that returns the appropriate data for DecorationRole may work, but it can be problematic to make it behave the way you want it.

0
source

You can also save images to icons and use QComboBox :: setIconSize () to avoid scaling.

0
source

Just reorient paintEvent. Here is the sketch code:

 void PenComboBox::paintEvent( QPaintEvent* pEvent) { QComboBox::paintEvent( pEvent); QVariant itemData = this->itemData( this->currentIndex(), Qt::DisplayRole); if( !itemData.isNull() && qVariantCanConvert<QPen>( itemData)) { QPainter painter(this); // .. etc } } 
-1
source

All Articles