models & editors in PyQt4



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



Relevant Pages

  • Re: Good practice when writing modules...
    ... def spam: ... My editor has a command that finds and lists me all the global imports ... having your editor trace these dependencies for you is ...
    (comp.lang.python)
  • Re: Eve - displaying ESC?
    ... DEF KEY=CONTROL-B SET WIDTH 132 ... To me, that's faster than first "teaching" the sequence to the editor, ... Unofficial Affordable OpenVMS Home Page: ... Unofficial OpenVMS Hobbyist Support Page: ...
    (comp.os.vms)
  • Re: adding "Print" menu in wxPython
    ... are the codes I am adding which make an editor and I ... I added the OnPrint method however i am leaving it up to you to build ... def CreateMenu: ...
    (comp.lang.python)
  • Re: models & editors in PyQt4
    ... Any other Property has its own editor and their control ... Hovewer i'm not sure about ColorProperty. ... You could create an empty placeholder widget in the createEditor ... def createEditor: ...
    (comp.lang.python)
  • Re: Language mavens: Is there a programming with "if then else ENDIF" syntax?
    ... "force" is too strong a word, but Python lends itself to if/elif ... def _dict: ... return ast.field, '%s.%s' % (metavar, ast.field) ... return ast.synonym, parent ...
    (comp.lang.python)