2016-03-20 15 views
0

Ich versuche, eine QListView mit QStyledItemDelegate zu erstellen, um Daten mehr organisieren Weg zu zeigen.QListView mit CustomWIdget mit QStyledItemDelegate

Ich ging durch this site, und alles in C++, und ich habe keine Ahnung davon, raten von der Syntax und Anrufe, die in der Post verwendet wurde, versuchte ich meinen Weg, um es zu erreichen, aber ich hatte kein Glück . Kann mir bitte jemand dabei helfen?

import sys, os 

from PyQt4 import QtGui, QtCore 


class ListView(QtGui.QListView): 
    def __init__(self, parent=None): 
     super(ListView, self).__init__(parent) 

     self._model = None 
     self._data = [ 
         [ 
         'Header: King Arthur', 
         'Project: TBN', 
         'Asset: arthur', 
         'Task name: Design doc', 
         'Start Date: Today', 
         'End Date: Next Monday' 
         ] 
        ] 
     self.set_model() 
     item_delegate = ItemDelegate() 
     self.setItemDelegate(item_delegate) 
     self.openPersistentEditor(self._model.createIndex(0, 0)) 

    def set_model(self): 
     self._model = ListModel(self._data, parent=self) 
     self.setModel(self._model) 


class ListModel(QtCore.QAbstractItemModel): 
    def __init__(self, data=[], parent=None): 
     super(ListModel, self).__init__(parent) 
     self._data = data 

    def rowCount(self, *arg): 
     return 1 

    def columnCount(self, *arg): 
     return len(self._data) 

    def data(self, index, role): 
     row = index.row() 
     column = index.column() 

     if role == QtCore.Qt.DisplayRole: 
      return QtCore.QVariant(' | '.join(self._data[column])) 

     return QtCore.QVariant() 

    def index(self, row, column, parent): 
     return self.createIndex(row, column) 

    def parent(self, index): 
     item = index.internalPointer() 
     if item: 
      return item.getParent() 
     else: 
      item = self.createIndex(index.row(), index.column()).internalPointer() 
      if item: 
       return item.getParent() 

     return QtCore.QModelIndex() 

class ItemDelegate(QtGui.QStyledItemDelegate): 
    def createEditor(self, parent, option, index): 
     item_data = str(index.data().toString()) 
     editor = Widget(item_data.split('|'), parent=parent) 
     return editor 

    def updateEditorGeometry(self, editor, option, index): 
     editor.setGeometry(option.rect) 

class Widget(QtGui.QWidget): 
    def __init__(self, widget_data=[], parent=None): 
     super(Widget, self).__init__(parent) 

     vbox = QtGui.QVBoxLayout(self) 
     key_font = QtGui.QFont() 
     key_font.setWeight(QtGui.QFont.Bold) 
     val_font = QtGui.QFont() 
     val_font.setWeight(QtGui.QFont.Normal) 

     for each_data in widget_data: 
      hbox = QtGui.QHBoxLayout() 
      key, value = each_data.split(':') 
      key_text = QtGui.QLabel(self) 
      val_text = QtGui.QLabel(self) 

      key_text.setToolTip('Key: %s' % key) 
      val_text.setToolTip('Value: %s' % value) 

      key_text.setText(key) 
      val_text.setText(value) 

      key_text.setFont(key_font) 
      val_text.setFont(val_font) 

      hbox.addWidget(key_text) 
      hbox.addWidget(val_text) 
      # vbox.addLayout(hbox) 


if __name__ == '__main__': 
    qapp = QtGui.QApplication([]) 
    app = ListView() 
    app.show() 
    sys.exit(qapp.exec_()) 
+1

Ihre Frage ist sehr vage. Was versuchst du zu erreichen und was genau ist das Problem, das du bekommst? Auch sehe ich nicht die Ähnlichkeit zwischen Ihrem Code und dem C++ Code des Blogs, zu dem Sie verlinken. In diesem Blog wird erläutert, wie Sie mithilfe eines Delegaten das Umbrechen von Wörtern in Zellen durchführen können. Versuchen Sie das zu tun? In diesem Fall sollten Sie wahrscheinlich auch die 'sizeHint'- und' paint'-Methoden des 'ListViewDelegate' implementieren. – titusjan

+0

Danke für die Antwort zurück titusjan. Ja, anstelle von Wordwrapping Text möchte ich CustomWidget zeigen, die Daten zeigt. Momentan wird Widget in QListView nicht richtig angezeigt. – Mahendra

Antwort

0

Sofern Sie einen zwingenden Grund haben die View/Model Muster zu verwenden, in den meisten Fällen, es wird leichter sein, das Widget/Item Muster zu verwenden - QListWidget und QListWidgetItem.

Die QItemDelegate und QStyledItemDelegate sind so konzipiert, dass sie unterklassifiziert werden. Anschließend definieren Sie Methoden, die für die Behandlung von Ereignissen, die Dimensionierung und das Zeichnen der Ansichten/Widgets zuständig sind.

class MyWidget(QtGui.QWidget): 

    def __init__(self, parent): 
     super(MyWidget, self).__init__(parent) 
     self.listwidget = QtGui.QListWidget(self) 
     self.delegate = MyDelegate(self, self.listwidget) 
     self.listwidget.setItemDelegate(self.delegate) 

     datas = [ 
      {'Header': 'Blah', 'Project': 'TBN'}, 
      {'Header': 'Other', 'Project': 'Something'}, 
     ] 
     for data in datas: 
      MyItem(self.listwidget, data)  


class MyItem(QtGui.QListWidgetItem): 

    def __init__(self, parent, data): 
     super(MyItem, self).__init__(parent) 
     self._data = data 


class MyDelegate(QtGui.QStyledItemDelegate): 

    def __init__(self, parent, listwidget): 
     super(MyDelegate, self).__init__(parent) 
     self.listwidget = listwidget 

    def sizeHint(self, option, index): 
     if index: 
      item = self.listwidget.itemFromIndex(index) 
      print item._data 
      # Do fontmetrics stuff from C++ article you linked 
      # using the text in the data dictionary. 

    def paint(self, painter, option, index): 
     # same thing, get the item using the index 
     # get the data from the item 
     # paint the data however you want.   
+0

Danke für Beispiel Brenden, In meinem Code hatte ich ein Problem, bei dem Widgets in Top-Corner stapeln, ich habe versucht, {paint} Methode Delegate-Klasse zu implementieren, und es wurde behoben – Mahendra

+0

Sie müssen Qlayouts verwenden, um Ihre Widgets zu positionieren –

+0

Ich benutze es bereits in der Widget-Klasse oben, vermisse ich etwas oder mache es nicht richtig? – Mahendra

0
class ItemDelegate(QtGui.QStyledItemDelegate): 
    def createEditor(self, parent, option, index): 
     item_data = str(index.data().toString()) 
     editor = Widget(item_data.split('|'), parent=parent) 
     return editor 

    def updateEditorGeometry(self, editor, option, index): 
     editor.setGeometry(option.rect) 
def paint(self, painter, option, index): 
     painter.save() 
     index.model().setData(index, option.rect.width(), Qt.UserRole+1) 

dieses Problem behoben