2014-12-03 3 views
1

Можно ли установить QItemDelegate на конкретном QTreeWidgetItem? Мне нужно покрасить некоторые из QTreeWidgetItem s с определенным цветом.Установить QItemDelegate на конкретный QTreeWidgetItem

Я предполагаю, что это возможно, поскольку у нас есть QAbstractItemView::setItemDelegateForRow, но я не могу понять, как. Я не могу использовать QAbstractItemView::setItemDelegateForRow, потому что мне нужно установить пользовательский делегат в дочерней строке внутри QTreeWidget.

Кто-нибудь знает, какое решение для этого?

+0

Вы можете установить делегат для всего виджета. Затем проверьте элемент в делегате, если он подходит для раскраски или нет. – Bowdzone

+0

@Bowdzone Можно ли получить доступ к 'QTreeWidgetItem' изнутри делегата? –

+0

Вы помните мой последний ответ, так что вы можете использовать что-то 'if (index.parent(). IsValid())' или 'if (index.parent(). Row() == 1)' вместо 'if (index .row()% 2) 'или проверить уникальное значение элемента? – Chernobyl

ответ

0

Вы можете получить доступ к QTreeWidget от вас делегировать красить рутина, чтобы проверить, если условие для закрашивания фона выполняется

void custom_delegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const 
{ 
    const QTreeWidget* tree_widget = qobject_cast<const QTreeWidget*>(qstyleoption_cast<const QStyleOptionViewItemV3*>(&option)->widget); 
    .... 
} 

или вы что-то храните в QModelIndexUserData как предложил Чернобыль. В этом случае я бы, однако, создать enum для флагов (если это применимо в вашем случае):

enum custom_painter_flags{ 
    paint_default = 0, 
    paint_background = 1 
}; 

void somewhere_creating_the_items() 
{ 
    QTreeWidgetItem* newitem = new QTreeWidgetItem(...); 
    newitem->setData(0, Qt::UserRole, QVariant::fromValue<int>(custom_painter_flags::paint_background)); 
} 

void custom_delegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const 
{ 
    custom_painter_flags painter_flags = static_cast<painter>(index.data(Qt::UserRole).value<int>()); 

    if(painter_flags & paint_background){ 
     .... 
    } 
} 

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

+0

Я думал о кастинге виджета, но он сломал все мои взгляды. Например: 'const QTreeWidget * tree_widget = ...' работает нормально, но после этого 'qDebug() << tree_widget-> currentItem() -> text (0);' например, разбивает все представления. Перерывы с 'QPaintDevice: не удается уничтожить окрасочное устройство, которое окрашивается. Может быть, я неправильно понял, как его использовать? – Chernobyl

+0

Извините, у меня нет решения этого с моей головы – Bowdzone

+0

Работал как шарм. Я использовал комбинацию вашего ответа и ответ @ Чернобыля. К сожалению, я не могу согласиться с обоими ответами, поэтому я буду поддерживать его и принимать ваши. Надеюсь, никто не будет слишком расстроен: -s С праздником! –

0

Вы можете использовать qss в QTreeWidgetItem для изменения цвета или цвета фона.

+0

Действительно, вы правы, но вы не можете менять цвета для некоторых 'QTreeWidgetItem'' и не изменять их для других, используя только' QSS'. Вот почему я создал пользовательский делегат. Но я не знаю, как установить его на определенные 'QTreeWidgetItem' или' QModelIndex'es в 'QTreeWidget'. –

0

Я сделал это для QTableWidget, вы должны проверить значение всего вашего QTreeWidgetItem и установить цвет фона/цвет.

Например, для моего QTableWidget я сделал что-то вроде этого в цикле:

если (хороший товар): MyQTableItem.setBackground (QtGui.QColor (255.255.255))

+0

Да, вы правы, но вы не можете настроить цвет текста для наведения или выбранных состояний элемента. Вот почему я выбрал для этого пользовательский делегат. –

+0

Да, вы правы. Извините, у меня больше нет идеи. – KarNal

+0

Большое спасибо, человек! –

2

Вы не можете используйте QTreeWidgetItem в делегате напрямую (возможно, вы можете хранить список этих элементов внутри делегатов, но я думаю, что он неэффективен), потому что делегаты работают с QModelIndex и данными внутри разных ролей. Вы можете установить данные на Qt::UserRole+1 и получить доступ к ним внутри делегата. Например:

QTreeWidgetItem *cities = new QTreeWidgetItem(ui->treeWidget); 
//... 
cities->setData(0,Qt::UserRole+1,"chosen one"); 

QTreeWidgetItem *osloItem = new QTreeWidgetItem(cities); 
//... 

QTreeWidgetItem *berlinItem = new QTreeWidgetItem(cities); 
//... 
berlinItem->setData(0,Qt::UserRole+1,"chosen one"); 

Внутри делегата (только пример):

void ItemDelegatePaint::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 
{ 
    QString txt = index.model()->data(index, Qt::DisplayRole).toString(); 

    if(option.state & QStyle::State_Selected) 
    { 
     if(index.data(Qt::UserRole+1).toString() == "chosen one") 
      painter->fillRect(option.rect,Qt::green); 
     else 
      painter->fillRect(option.rect, option.palette.highlight()); 
    }else 
    if(option.state & QStyle::State_MouseOver) 
    { 
     if(index.data(Qt::UserRole+1).toString() == "chosen one") 
      painter->fillRect(option.rect,Qt::yellow); 
     else 
      painter->fillRect(option.rect, Qt::transparent); 
    } 
    else 
    { 
     QStyledItemDelegate::paint(painter,option,index); 
    } 
} 
+0

Это интересно, что вы говорите, и я думаю, что это сработает. Но не 'Qt :: UserRole + 1' небольшой взлом? :-) –

+1

@JacobKrieg Функция отображения для отображения, редактирования для редактирования, украшения для изображений и т. Д. Теперь вам нужна дополнительная информация, и вы используете 'Qt :: UserRole + 1'. Конечно, лучше использовать 1 или 0 вместо выбранного. Это не что-то плохое, в любом случае QTreeWidget + QTreeWidgetItem потребляет гораздо больше места, чем пользовательский QAbstractItemModel (Summerfield доказывает это в книгах), поэтому это несколько КБ или МБ не разрушит ваш проект, я думаю. – Chernobyl

+0

Спасибо! Давайте подождем @Bowdzone, чтобы опубликовать его решение, мне тоже интересно его идея. –

Смежные вопросы