How to make QCombobox painting item delegate for it's current Item? (Qt 4)

QCombobox set Item delegate not painting for current Item..

I am trying to create a combo box showing different line types (Solid, Dotted, Dash etc). Currently i am setting item delegate for its content so as to draw/paint line type instead of displaying names. All line types are drawing currectly but as soon as i am selecting any line type from the combobox, the current index of combo box is displaying just the line name and not painting it. How can i make it paint the selected line type on the current combo box index?

Answers


Delegate to paint items in combo popup:

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 paint current item in combo. You can, of course, paint it manually, but there is the simple way to draw combo box control itself (if you want an arrowbutton or smth in the current):

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)

I think I've encountered this problem before, having a delegate that displays the line correctly in the drop-down menu but not in the combo box itself.

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

"For the text and icon in the combobox label, the data in the model that has the Qt::DisplayRole and Qt::DecorationRole is used."

I suspect that an approach which involves a model that returns suitable data for the DecorationRole might work, but it could be problematic to get it to behave just the way you want it to.


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


Just override paintEvent. Here is some 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
  }
}

Need Your Help

Copying files into the source code before building a deploy package with MsBuild on TFS

visual-studio visual-studio-2012 tfs msbuild web-deployment

I'm using TFS as a build server to use MsBuild for building and packaging a solution into a web deploy-package.

Bootstrap navbar left to right

css twitter-bootstrap navbar

It may be stupid but I do not have any idea how to make bootstrap navbar from right to left, I'm creating an arabic website, so i want to have 'home' nav from the right .