2010-08-12 5 views
2

Je souhaite afficher chaque ligne avec du code HTML. Le rendu fonctionne mais, au moins pour moi, les éléments ne peuvent pas être sélectionnés individuellement.Impossible de sélectionner un élément dans QListView avec QStyledItemDelegate personnalisé

import sys 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

#################################################################### 
def main(): 
    app = QApplication(sys.argv) 
    w = MyWindow() 
    w.show() 
    sys.exit(app.exec_()) 


list_data = [1,2,3,4] 

#################################################################### 
class MyWindow(QWidget): 
    def __init__(self, *args): 
     QWidget.__init__(self, *args) 

     # create table   
     lm = MyListModel(list_data, self) 
     lv = QListView() 
     lv.setModel(lm) 
     lv.setItemDelegate(HTMLDelegate(self)) 

     # layout 
     layout = QVBoxLayout() 
     layout.addWidget(lv) 
     self.setLayout(layout) 

#################################################################### 
class MyListModel(QAbstractListModel): 
    def __init__(self, datain, parent=None, *args): 
     """ datain: a list where each item is a row 
     """ 
     QAbstractListModel.__init__(self, parent, *args) 
     self.listdata = datain 

    def rowCount(self, parent=QModelIndex()): 
     return len(self.listdata) 

    def data(self, index, role): 
     if index.isValid() and role == Qt.DisplayRole: 
      return QVariant(self.listdata[index.row()]) 
     else: 
      return QVariant() 

class HTMLDelegate(QStyledItemDelegate): 
    def paint(self, painter, option, index): 
     painter.save() 

     model = index.model() 
     record = model.listdata[index.row()] 
     doc = QTextDocument(self) 
     doc.setHtml("<b>%s</b>"%record) 
     doc.setTextWidth(option.rect.width()) 
     ctx = QAbstractTextDocumentLayout.PaintContext() 

     painter.translate(option.rect.topLeft()); 
     painter.setClipRect(option.rect.translated(-option.rect.topLeft())) 
     dl = doc.documentLayout() 
     dl.draw(painter, ctx) 
     painter.restore() 


    def sizeHint(self, option, index): 
     model = index.model() 
     record = model.listdata[index.row()] 
     doc = QTextDocument(self) 
     doc.setHtml("<b>%s</b>"%record) 
     doc.setTextWidth(option.rect.width()) 
     return QSize(doc.idealWidth(), doc.size().height()) 
    def flags(self, index): 
     return Qt.ItemIsEnabled | Qt.ItemIsSelectable 
#################################################################### 
if __name__ == "__main__": 
    main() 

Répondre

2

Je crois que ce que vous devez faire est de détecter les éléments sélectionnés dans votre méthode de HTMLDelegate.paint et remplir l'arrière-plan avec la couleur « highlight » si ces éléments détectés. Je suis un peu changé votre méthode de peinture, pls, vérifier si cela fonctionne pour vous

def paint(self, painter, option, index): 
    painter.save() 

    # highlight selected items 
    if option.state & QtGui.QStyle.State_Selected: 
     painter.fillRect(option.rect, option.palette.highlight()); 

    model = index.model() 
    record = model.listdata[index.row()] 
    doc = QTextDocument(self) 
    doc.setHtml("<b>%s</b>"%record) 
    doc.setTextWidth(option.rect.width()) 
    ctx = QAbstractTextDocumentLayout.PaintContext() 

    painter.translate(option.rect.topLeft()); 
    painter.setClipRect(option.rect.translated(-option.rect.topLeft())) 
    dl = doc.documentLayout() 
    dl.draw(painter, ctx) 

    painter.restore() 

espérons que cette aide, ce qui est

+0

Juste coppied les éléments surbrillance # sélectionnés et il a résolu mon problème. Très bien. – Rodrigo

Questions connexes