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.QAbstractItemV iew.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_())
#--------------------------------------------