PyQT/QListWidget: Text formatieren

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Gab
User
Beiträge: 21
Registriert: Montag 17. August 2009, 14:45

Hallo,

ich habe in einer PyQT-Anwendung ein QListWidget.
Der Text jedes Items besteht aus Nutzer, Zeitstempel, Text und sollte so dargestellt werden:
Nutzer | Zeitstempel
Text
Wie stelle ich das an? Ich verwirre mich gerade in Delegates und komme damit gar nicht klar.
EmaNymton
User
Beiträge: 174
Registriert: Sonntag 30. Mai 2010, 14:07

Ich schiebe mal vorweg, dass ich nicht behaupte, dass dies die beste Lösung ist. Da mich aber das Ganze auch interessiert, ich aber eher noch Anfänger bin, habe ich mich mal daran versucht und aus der Doku sowie Beispielen im Netz etwas gebastelt.

Du musst dir ein eigenes Delegate erzeugen, das von QStyledItemDelegate erbt. Darin kannst du die paint-Methode und die sizeHint-Methode so überschreiben, wie unten im Quelltext. Die Daten holst du dir aus dem Model, ich übergebe hier halt die ganze Liste, keine Ahnung, in welcher Form deine Daten vorliegen.

Vielleicht kann mal jemand mit mehr Ahnung als ich was dazu sagen, ob man das so machen kann, oder ob es da noch bessere/effektivere Möglichkeiten gibt.

Code: Alles auswählen

# -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys

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

        # create objects
        list_data = [['Nutzer1','Zeitstempel1','Text1'],
                     ['Nutzer2','Zeitstempel2','Text2'],
                     ['Nutzer3','Zeitstempel3','Text3'],
                     ['Nutzer4','Zeitstempel4','Text4']]
        listmodel = MyListModel(list_data, self)
        listview = QListView(self)
        delegate = MyDelegate(self)
        listview.setModel(listmodel)
        listview.setItemDelegate(delegate)

        # layout
        layout = QVBoxLayout()
        layout.addWidget(listview)
        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 MyDelegate(QStyledItemDelegate):
    def __init__(self, parent=None, *args):
        QStyledItemDelegate.__init__(self, parent, *args)

    def paint(self, painter, option, index):
        painter.save()
        user, timestamp, text = index.data(Qt.DisplayRole).toStringList()
        rect = option.rect
        #first line
        painter.drawText(QRect(rect.left(),rect.top(),
                         rect.width(), rect.height()/2), 
                         Qt.AlignLeft,
                         "{user} | {stamp}".format(user=user,stamp=timestamp))
        #second line
        font = painter.font()
        font.setWeight(QFont.Bold)
        painter.setFont(font)
        painter.drawText(QRect(rect.left(),rect.top()+rect.height()/2,
                         rect.width(), rect.height()), Qt.AlignLeft, text)
        painter.restore()

    def sizeHint(self, option, index):
        result = QStyledItemDelegate().sizeHint(option, index);
        result.setHeight(result.height()*2)
        return result
        

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())
lunar

@Gab Hast Du versucht, einfach mal Rich Text für die Beschriftung eines Elements zu verwenden?
Antworten