2009-12-30 74 views
12

我使用double-dispatch创建一个样式化的QTreeView来解析数据项的特定委托,这非常有效。我从QStyledItemDelegate中分派了代表以利用样式表,使设计师能够在代码之外设计UI。对样式表使用多个QStyledItemDelegate

不幸的是,我一直无法解决CSS的不同风格。如何选择和使用样式表中指定的项目子控件样式?

的CSS我与测试:

QTreeView::item:selected { 
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #dddddd, stop: 1 #888888); 
} 
QTreeView::item:selected[role="title"] { 
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fde7ef, stop: 1 #f1cbda); 
} 
QTreeView::item:selected[role="entry"] { 
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1); 
} 

我代表渲染类:

class VisitingDelegate(QtGui.QAbstractItemDelegate): 
    def __init__(self, parent=None): 
     super(VisitingDelegate,self).__init__(parent) 
     roles = {} 
     self.renderRoles = roles 

     d = TitleDelegate(parent) 
     d.setProperty("role", "title") 
     roles['title'] = d 

     d = EntryDelegate(parent) 
     d.setProperty("role", "entry") 
     roles['entry'] = d 

    def delegateForIndex(self, mi): 
     role = mi.model().data(mi, "renderRole") 
     return self.renderRoles[role] 

    def paint(self, painter, option, mi): 
     dg = self.delegateForIndex(mi) 
     return dg.paint(painter, option, mi) 
    def sizeHint(self, option, mi): 
     dg = self.delegateForIndex(mi) 
     return dg.sizeHint(option, mi) 

class TextDocumentDelegate(QtGui.QStyledItemDelegate): 
    fmt = "<font color='%(color)s'>%(text)s</font)>" 
    def paint(self, painter, option, mi): 
     painter.save() 

     opt = QtGui.QStyleOptionViewItemV4(option) 
     self.initStyleOption(opt, mi) 
     opt.text = '' 

     style = opt.widget.style() 
     style.drawControl(style.CE_ItemViewItem, opt, painter, opt.widget) 

     textRect = style.subElementRect(style.SE_ItemViewItemText, opt, opt.widget); 
     doc = self.asTextDoc(option, mi) 
     painter.translate(textRect.topLeft()) 
     doc.drawContents(painter) 

     painter.restore() 

    def sizeHint(self, option, mi): 
     doc = self.asTextDoc(option, mi) 
     sz = doc.size() 
     sz = QtCore.QSize(sz.width(), sz.height()) 
     return sz 

    def asTextDoc(self, option, mi): 
     info = {} 
     info['text'] = mi.model().data(mi, Qt.DisplayRole) 

     doc = QtGui.QTextDocument() 
     doc.setDefaultFont(option.font) 
     pal = option.palette 
     if option.state & QtGui.QStyle.State_Selected: 
      color = pal.color(pal.HighlightedText) 
     else: color = pal.color(pal.Text) 
     info['color'] = color.name() 

     doc.setHtml(self.fmt % info) 
     return doc 

class EntryDelegate(TextDocumentDelegate): 
    pass 
class TitleDelegate(TextDocumentDelegate): 
    fmt = "<h3><font color='%(color)s'>%(text)s</font)></h3>" 
+0

你确定这个代码被实际调用?你如何设置代表? – fabrizioM 2010-01-19 09:19:21

+0

那么,我宁可重写itemDelegate(QModelIndex),除非它没有标记为虚拟。相反,我使用'setItemDelegate(VisitingDelegate())',在[用Python和Qt进行快速GUI编程] [1]中的类似抽象之后进行建模。不幸的是,这本书的版本没有解决与代表使用CSS的问题。 [1]:http://www.qtrac.eu/pyqtbook.html – 2010-01-19 17:25:35

回答

1

不同的风格,不能选择这种方式。选择样式表规则的属性取自QWidget(本例中为QTreeView),而不是委托。代表不是一个小部件,并且没有代表单个项目的小部件。你举的例子可以通过添加其中从部件得到的样式打印显示此:

style = opt.widget.style() 
print opt.widget 

这将显示该控件的样式QTreeView则。由于小部件对于两个代理都相同,因此它不能具有两个值的角色设置。

即使样式表是这么写的,它看起来像的角色是否与项目相关的规则选择就像是写为:

QTreeView[role="title"]::item:selected