Как я могу изменить цвет определенной ветви в QTreeView?

1

У меня есть QTreeView, и я выяснил, как установить его стиль, используя setStyleSheet в моем основном классе:

self.view.setStyleSheet("""
    QTreeView::item {
        margin: 2px;
    }
""")

Это создаст стиль всего QTreeView. Но я хочу, чтобы некоторые элементы в дереве были выделены жирным шрифтом. Когда я создаю ветки (используя [the parent widget].appendRow("the name of the item")), есть ли способ "пометить" или изолировать определенные элементы, чтобы их можно было создать одинаково? Я думаю, что ответ имеет какое-то отношение к свойствам "AccessibleName" или "ObjectName", но мне трудно найти документацию по нему.

Обновление: Это то, что у меня есть до сих пор:

#!/usr/bin/python
# -*- coding: utf-8 -*-

from __future__ import division
from __future__ import print_function
from future_builtins import *

import os, sys
from PySide.QtCore import *
from PySide.QtGui import *

path_to_media = '/Volumes/show/vfx/webisodes/%d1%/seq/%d2%/%d3%/renders/2d/comp/'

class FileTree(QTreeView):
    """Main file tree element"""
    def __init__(self):
        QTreeView.__init__(self)
    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Space or event.key() == Qt.Key_Return:
            index = self.selectedIndexes()[0]
            crawler = index.model().itemFromIndex(index)
            if crawler.uri:
                print("launching", crawler.uri)
                p = os.popen(('open -a "RV.app" "'+ crawler.uri) +'"', "r")
        QTreeView.keyPressEvent(self, event)

class Branch(QStandardItem):
    """Branch element"""
    def __init__(self, label, uri = None, tag = None):
        QStandardItem.__init__(self, label)
        self.uri = uri

class AppForm(QMainWindow):
    def __init__(self, parent = None):
        super(AppForm, self).__init__(parent)
        self.model = QStandardItemModel()
        self.view = FileTree()
        self.view.setStyleSheet("""
            QTreeView::item {
                margin: 2px;
            }
        """)
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.view.setModel(self.model)
        self.setCentralWidget(self.view)
        self.Grow()
        # self.view.setSortingEnabled(True)

    def Grow(self):
        """Populates FileTree (using BuildBranch())"""
        global path_to_media
        self.path = {}
        self.path['source'] = path_to_media
        self.path['parts'] = []
        self.path['depth'] = 0
        self.path['crawl'] = {}
        for i in self.path['source'].split('%'):
            if i[0] == "d" and i[1].isdigit():
                self.path['depth'] += 1
            else:
                self.path['parts'].append(i)
        self.BuildBranch(self.path['parts'], self.path['depth'], parentWidget = self.model.invisibleRootItem())

    def BuildBranch(self, parts, depth, uri = '', count = 0, parent = '', parentWidget = ''):
        """Recursively crawls folder structure and adds appropriate branches"""
        if not uri: uri = parts[0]
        else: uri += parent + parts[count]
        try:
            if os.listdir(uri):
                for i in os.listdir(uri):
                    if i[0] != '.':
                        if count != depth:
                            if os.path.isdir(uri):
                                thisWidget = Branch(i)
                                parentWidget.appendRow(thisWidget)
                                self.BuildBranch(parts, depth, uri, count + 1, i, parentWidget = thisWidget)
                            else:
                                thisWidget = Branch(i)
                                parentWidget.appendRow(thisWidget)
                        elif count == depth:
                            thisWidget = Branch(i, uri + i, 'media')
                            parentWidget.appendRow(thisWidget)
            else:
                print("nothing here; nuking " + parent)
                # Need to add code to nuke unused branch
        except OSError:
            print("Folder structure error... nuking the branch")
            # Need to add code to nuke unused branch

def main():
    app = QApplication(sys.argv)
    form = AppForm()
    form.resize(800, 600)
    form.setWindowTitle('Qt Dailies')
    form.show()
    app.exec_()

if __name__ == "__main__":
    main()

Обновление 2: Хорошо, я изменил свой класс Branch, чтобы, если 'bold' передан ему, он делает ветку полужирным (в теории)...

class Branch(QStandardItem):
    def __init__(self, label, uri = None, tag = None):
        QStandardItem.__init__(self, label)
        self.uri = uri
        if tag == 'bold':
            self.setData(self.createBoldFont(), Qt.FontRole)
    def createBoldFont(self):
        if self.font: return self.font
        self.font = QFont()
        self.font.setWeight(QFont.Bold)
        return self.font

... но пока код работает, ничего не происходит. Что я до сих пор не получаю?

Теги:
qt

2 ответа

1
Лучший ответ

Архитектура модели Qt моделирует данные, описывающие различные выполняемые роли. Например, есть роль для редактирования данных, отображения данных и т.д. Вас интересует роль шрифта (например, Qt::FontRole), поскольку шрифт имеет перечисление веса, для которого полужирным является одно значение.

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

def should_be_bolded(self, item):
    return 1 # your condition checks

Теперь просто установите вес шрифта и задайте роль шрифта элемента с помощью метода setData:

def BuildBranch(...):
    thisWidget = Branch(i)
    if self.should_be_bolded(thisWidget):
        thisWidget.setData(self.createBoldFont(), Qt.FontRole)

def createFont(self):
    if self.font: return self.font
    self.font = QFont()
    self.font.setWeight(QFont.Bold)
    return self.font

Но подождите... у вас уже есть подкласс QtandardItem, поэтому вы можете использовать это:

class Branch(QStandardItem):
    """Branch element"""
    def __init__(self, label, uri = None, tag = None):
        QStandardItem.__init__(self, label)
        self.uri = uri
        if self.should_be_bolded():
            self.bold_myself()

Вам нужно будет исправить методы should_be_bolded и bold_myself, соответственно bold_myself их, но, надеюсь, вы bold_myself.

Стивен отметил, что вы также можете подклассифицировать один из QAbstractItemModel, например, QStandardItemModel который вы используете, и вернуть определенный Qt.FontRole. Его способ делает это знание подразумеваемым в модели. Решите, где это знание лучше всего, и поместите его в наиболее подходящее место, будь то в элементе, алгоритме создания дерева, модели или даже модели представления.

  • 0
    Хорошо, я думал, что понял, но когда я переписал свой класс Branch, чтобы получить смелый FontRole, ничего не произошло. Я добавил новый код класса в свой первый пост.
  • 0
    Предполагая, что вы передаете жирный тег, это выглядит правильно. Я постараюсь проверить это и вернусь к вам.
Показать ещё 1 комментарий
0

В вашем методе data() вы можете добавить код для установки шрифта в зависимости от содержимого элемента. Например, если вы хотите выделить все в одной строке,

def data(self, index, role):

    if role == QtCore.Qt.FontRole:
       if index.row() == 1:
           boldFont = QtGui.QFont()
           boldFont.setBold(True)
           return boldFont

Вам просто нужен способ получить имя вашей ветки, когда ему присваивается индекс. Это зависит от реализации вашей модели дерева.

Хороший пример имеет учебник Qt Model/View, хотя он находится в C++. Посмотрите раздел 2.2 (Расширение примера только для чтения с ролями).

  • 0
    Я не совсем уверен, что вы подразумеваете под методом data() - я пытался использовать QT в течение нескольких дней, так что это все довольно запутанно для меня (и у меня много проблем с попытками чтобы понять примеры C ++). Я добавил свой код в исходное сообщение.
  • 0
    @Stephen - он не использует пользовательскую модель на данный момент, поэтому немного более подробное объяснение, вероятно, будет полезно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню