I have a QTreeView, and I’ve figured out how to set its style by using setStyleSheet in my main class:
self.view.setStyleSheet("""
QTreeView::item {
margin: 2px;
}
""")
That will style the entire QTreeView. But I want certain items in the tree to be bolded. When I create the branches (using [the parent widget].appendRow("the name of the item")), is there a way to ‘tag’ or isolate specific items so it can be styled the same way? I think the answer has something to do with the ‘AccessibleName’ or ‘ObjectName’ properties, but I’m having trouble finding documentation on it.
Update: This is what I have so far:
#!/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()
Update 2: Okay, I modified my Branch class so that if ‘bold’ is passed to it, it makes the branch bold (in theory)…
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
… but while the code runs, nothing seems to happen. What am I still not getting?
Qt’s model-view architecture allows for data that describes the different roles being performed. For example, there is a role for editing data, displaying data, etc. You’re interested in the font role (i.e.
Qt::FontRole) as the font has a weight enum of which bold is one value.When you build your branches you first need to identify which items should be bolded. I’ll assume you have a method like such that can identify whether or not they should be bold:
Now just set the weight on the font and set the font role of the item using its setData method:
But wait… you already have a subclass of QtandardItem, so you can use that:
You’ll have to fix the
should_be_boldedandbold_myselfmethods, cleaning up accordingly, but hopefully you get the point.Stephen pointed out that you can also subclass one of the
QAbstractItemModels, like theQStandardItemModelyou’re using, and return a specificQt.FontRole. His way makes that knowledge implicit in the model. Decide where that knowledge best belongs and place it in the most appropriate place, whether it’s in the item, the tree-creation algorithm, the model, or even a view model.