Как сделать так, чтобы QCombobox отображал делегат для текущего элемента? (Qt 4) - PullRequest
4 голосов
/ 05 февраля 2009

QCombobox set Делегат элемента не рисует для текущего элемента ..

Я пытаюсь создать поле со списком, показывающее различные типы линий (сплошная, пунктирная, тире и т. Д.). В настоящее время я устанавливаю делегат элемента для его содержания. чтобы нарисовать / нарисовать тип линии вместо отображения имен. Все типы линий рисуются правильно, но как только я выбираю любой тип линии из combobox, текущий индекс поля со списком отображает только имя строки, а не рисует ее. Как сделать так, чтобы он рисовал выбранный тип линии на текущем индекс поля со списком?

Ответы [ 4 ]

3 голосов
/ 18 марта 2010

Делегат для рисования элементов в выпадающем списке:

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 для рисования текущего элемента в комбо. Конечно, вы можете нарисовать его вручную, но есть простой способ нарисовать сам элемент управления комбинированного блока (если вы хотите кнопку со стрелкой или что-то в текущем):

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)
0 голосов
/ 13 марта 2009

Вы также можете сохранять изображения в виде значков и использовать QComboBox :: setIconSize (), чтобы избежать масштабирования.

0 голосов
/ 08 мая 2009

Просто переопределить paintEvent. Вот код скетча:

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
  }
}
0 голосов
/ 27 февраля 2009

Мне кажется, я сталкивался с этой проблемой раньше, имея делегата, который правильно отображает строку в раскрывающемся меню, но не в самом поле со списком.

В документации (http://doc.trolltech.com/4.4/qcombobox.html) указано, что:

"Для текста и значка в метке комбинированного списка используются данные в модели, которые имеют Qt :: DisplayRole и Qt :: DecorationRole."

Я подозреваю, что подход, включающий модель, которая возвращает подходящие данные для DecoRole, мог бы работать, но было бы проблематично заставить его вести себя так, как вы этого хотите.

...