models & editors in PyQt4

Skink spam at me.please
Wed Aug 30 07:43:39 EDT 2006


Hi,

I created simple property classes with editing option, but since i'm not 
too much experienced in PyQt4 i'd like to ask if i handle ColorProperty 
changing right. Any other Property has its own editor and their control 
flow is imho ok. Hovewer i'm not sure about ColorProperty.

What i do is: in createEditor(self, parent, option, index) i call 
QtGui.QColorDialog.getColor() and return None

What do you think? Is it Ok?

thanks,
skink

#--------------------------------------------
import sys
from PyQt4 import QtGui, QtCore

class PropertyDelegate(QtGui.QItemDelegate):
     def __init__(self, model):
         QtGui.QItemDelegate.__init__(self, None)
         self.model = model
     def createEditor(self, parent, option, index):
         if index.column() == 0:
             return None
         item = self.model.getItem(index)
         return item.createEditor(parent, option, index)
     def setEditorData(self, editor, index):
         item = self.model.getItem(index)
         item.setEditorData(editor, index)
     def setModelData(self, editor, model, index):
         item = self.model.getItem(index)
         item.setModelData(editor, model, index)
#    def updateEditorGeometry(self, editor, option, index):
#        editor.setGeometry(option.rect)
     def paint(self, painter, option, index):
         item = self.model.getItem(index)
         if isinstance(item, ColorProperty) and index.column() == 1:
             item.paint(painter, option, index)
             return
         QtGui.QItemDelegate.paint(self, painter, option, index)

class SimpleModelItem:
     def __init__(self, parent=0):
         self._index = []
         self._children = []
         self._parent = parent
         if parent:
             parent._children.append(self)
         self._parent = parent
     def parent(self):
         return self._parent
     def children(self):
         return self._children
     def addIndex(self, index):
         self._index.append(index)
     def childId(self, child):
         return id(self._children[child])
     def index(self, column=0):
         return self._index[column]

class Property(SimpleModelItem):
     def __init__(self, parent=0, name="", data=[]):
         SimpleModelItem.__init__(self, parent)
         self._data = data
         self._name = name
     def data(self, index):
         return self._data[index.column()]
     def name(self):
         return self._name
     def createEditor(self, parent, option, index):
         return None
     def setEditorData(self, editor, index):
         return
     def setModelData(self, editor, model, index):
         return

class StringProperty(Property):
     def __init__(self, parent, name, t):
         Property.__init__(self, parent, name, [t, ""])
     def createEditor(self, parent, option, index):
         editor = QtGui.QLineEdit(parent)
         return editor
     def setEditorData(self, editor, index):
         value = index.model().getObjectData(self.name())
         editor.setText(value)
     def setModelData(self, editor, model, index):
         index.model().setObjectData(self.name(), editor.text())
     def data(self, index):
         if index.column() == 0:
             return self._data[0]
         else:
             return str(index.model().getObjectData(self.name()))
class IntegerProperty(Property):
     def __init__(self, parent, name, t):
         Property.__init__(self, parent, name, [t, ""])
     def createEditor(self, parent, option, index):
         editor = QtGui.QSpinBox(parent)
         editor.setMaximum(256*256)
         return editor
     def setEditorData(self, editor, index):
         value = index.model().getObjectData(self.name())
         editor.setValue(value)
     def setModelData(self, editor, model, index):
         index.model().setObjectData(self.name(), editor.value())
     def data(self, index):
         if index.column() == 0:
             return self._data[0]
         else:
             return str(index.model().getObjectData(self.name()))

class SizeProperty(Property):
     def __init__(self, parent, name, t):
         Property.__init__(self, parent, name, [t, ""])
         self.items = []
         self.items.append(IntegerProperty(self, name+":x", "x"))
         self.items.append(IntegerProperty(self, name+":y", "y"))
         self.items.append(IntegerProperty(self, name+":w", "width"))
         self.items.append(IntegerProperty(self, name+":h", "height"))

class ColorProperty(Property):
     def __init__(self, parent, name, t):
         Property.__init__(self, parent, name, [t, ""])
     def createEditor(self, parent, option, index):
         color = QtGui.QColorDialog.getColor()
         if color.isValid():
             index.model().setObjectData(self.name(), color)
         return None
     def paint(self, painter, option, index):
         r = option.rect
         if option.state & QtGui.QStyle.State_Selected:
             painter.fillRect(r, option.palette.highlight())
         color = index.model().getObjectData(self.name())
         colorStr = color.name()
         tr = painter.boundingRect(r, QtCore.Qt.AlignLeft, colorStr)
         w = tr.width() + 4
         painter.fillRect(r.x() + 1, r.y() + 1, r.width() - 3 - w, 
r.height() - 3, QtGui.QBrush(color))
         painter.setPen(QtCore.Qt.black)
         painter.drawRect(r.x() + 1, r.y() + 1, r.width() - 3 - w, 
r.height() - 3)
         r.setLeft(r.x() + r.width() + 1 - w)
         painter.drawText(r, QtCore.Qt.AlignLeft, colorStr)

class EnumProperty(Property):
     def __init__(self, parent, name, t, te):
         Property.__init__(self, parent, name, [t, ""])
         self.te = te
     def createEditor(self, parent, option, index):
         editor = QtGui.QComboBox(parent)
         i = 0
         for item in self.te:
             editor.addItem(item, QtCore.QVariant(i))
             i += 1
         return editor
     def setEditorData(self, editor, index):
         index = index.model().getObjectData(self.name())
         editor.setCurrentIndex(index)
     def setModelData(self, editor, model, index):
         index.model().setObjectData(self.name(), editor.currentIndex())
     def data(self, index):
         if index.column() == 0:
             return self._data[0]
         else:
             index = index.model().getObjectData(self.name())
             return self.te[index]

class BooleanProperty(EnumProperty):
     def __init__(self, parent, name, t):
         EnumProperty.__init__(self, parent, name, t, ["False", "True"])

#-----------------------------------------------------------------------
class SimpleModel(QtCore.QAbstractItemModel):
     def __init__(self, root, parent=None):
         QtCore.QAbstractItemModel.__init__(self, parent)
         self.ids = {}

         self.root = root
         self.root.addIndex(QtCore.QModelIndex())
         self.ids[id(self.root)] = self.root

         self.walk(root)
     def walk(self, parent):
         row = 0
         for child in parent.children():
             _id = id(child)
             self.ids[_id] = child
             child.addIndex(self.createIndex(row, 0, _id))
             child.addIndex(self.createIndex(row, 1, _id))
             self.walk(child)
             row += 1
     def getItem(self, index):
         if not index.isValid():
             return self.root
         else:
             return self.ids[index.internalId()]
 
#-----------------------------------------------------------------------
     def setObject(self, obj):
         self.obj = obj
         self.reset()
     def getObjectData(self, name):
         #print "getObjectData", name, self.obj[name]
         return self.obj[name]
     def setObjectData(self, name, value):
         #print "setObjectData", name, value
         self.obj[name] = value
 
#-----------------------------------------------------------------------
     def index(self, row, column, parent):
         parentItem = self.getItem(parent)
         childItem = self.ids[parentItem.childId(row)]
         return childItem.index(column)
     def parent(self, index):
         childItem = self.getItem(index)
         parentItem = childItem.parent()
         return parentItem.index()
     def rowCount(self, parent):
         parentItem = self.getItem(parent)
         return len(parentItem.children())
     def columnCount(self, parent):
         return 2
     def data(self, index, role):
         if not index.isValid() or role != QtCore.Qt.DisplayRole:
             return QtCore.QVariant()
         item = self.getItem(index)
         return QtCore.QVariant(item.data(index))
     def flags(self, index):
         if not index.isValid():
             return QtCore.Qt.ItemIsEnabled
         else:
             return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable 
| QtCore.Qt.ItemIsEditable
     def headerData(self, section, orientation, role):
         if orientation == QtCore.Qt.Horizontal and role == 
QtCore.Qt.DisplayRole:
             if section == 0:
                 return QtCore.QVariant("Name")
             else:
                 return QtCore.QVariant("Value")
         return QtCore.QVariant()

objAData = {
     "width": 6, "size:x": 10, "size:y": 15, "size:w": 20, "size:h": 25,
     "frameType": 0, "visible": 1, "color": QtGui.QColor(QtCore.Qt.red),
     "name": "foobar A"
}
objBData = {
     "width": 66, "size:x": 100, "size:y": 150, "size:w": 200, "size:h": 
250,
     "frameType": 1, "visible": 0, "color": QtGui.QColor(QtCore.Qt.green),
     "name": "foobar B"
}
objCData = {
     "width": 666, "size:x": 1000, "size:y": 1500, "size:w": 2000, 
"size:h": 2500,
     "frameType": 2, "visible": 1, "color": QtGui.QColor(QtCore.Qt.blue),
     "name": "foobar C"
}

root = Property()
newItem = StringProperty(root, "name", "Name")
newItem = IntegerProperty(root, "width", "Item Width")
newItem = ColorProperty(root, "color", "Background Color")
newItem = SizeProperty(root, "size", "Item Size")
newItem = EnumProperty(root, "frameType", "Frame Type", ["Solid", 
"Dashed", "None"])
newItem = BooleanProperty(root, "visible", "Visibility")

class Widget(QtGui.QWidget):
     def __init__(self, parent=None):
         QtGui.QWidget.__init__(self, parent)
         mainLayout = QtGui.QVBoxLayout()

         self.treeView = QtGui.QTreeView()
 
self.treeView.setEditTriggers(QtGui.QAbstractItemView.SelectedClicked)
         self.model = SimpleModel(root)
         self.delegate = PropertyDelegate(self.model)
         self.treeView.setItemDelegate(self.delegate)
         self.model.setObject(objAData)
         self.treeView.setModel(self.model)
         mainLayout.addWidget(self.treeView)
         b1 = QtGui.QPushButton("Object A")
         self.connect(b1, QtCore.SIGNAL("clicked()"), self.objAClicked)
         mainLayout.addWidget(b1)
         b2 = QtGui.QPushButton("Object B")
         self.connect(b2, QtCore.SIGNAL("clicked()"), self.objBClicked)
         mainLayout.addWidget(b2)
         b3 = QtGui.QPushButton("Object C")
         self.connect(b3, QtCore.SIGNAL("clicked()"), self.objCClicked)
         mainLayout.addWidget(b3)
         self.setLayout(mainLayout)
     def objAClicked(self):
         self.model.setObject(objAData)
     def objBClicked(self):
         self.model.setObject(objBData)
     def objCClicked(self):
         self.model.setObject(objCData)


if __name__ == "__main__":
     app = QtGui.QApplication(sys.argv)
     widget = Widget()
     widget.show()
     sys.exit(app.exec_())
#--------------------------------------------



More information about the Python-list mailing list