2009-12-30 76 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