473,224 Members | 1,410 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,224 software developers and data experts.

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.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_())
#--------------------------------------------
Aug 30 '06 #1
3 3170
Skink wrote:
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?
It should be OK - it shouldn't crash, anyway. It depends on the view
doing the right thing when it finds that it hasn't received an editor
widget.

You could create an empty placeholder widget in the createEditor()
method, call QColorDialog.getColor() with the existing color from the
model in setEditorData(), record the color returned by the dialog in
some internal instance variable, and finally set the data in the model
when setModelData() is called:

class ColorProperty(Property):
...
def createEditor(self, parent, option, index):
return QtGui.QWidget(parent)
def setEditorData(self, editor, index):
self.color = QtGui.QColorDialog.getColor(
index.model().getObjectData(self.name()))
def setModelData(self, editor, model, index):
if self.color.isValid():
index.model().setObjectData(self.name(), self.color)
...

I find it strange that you have to triple-click to edit any of the
items in your example. Do you see the same behaviour?

David

Aug 30 '06 #2
David Boddie wrote:
>
It should be OK - it shouldn't crash, anyway. It depends on the view
doing the right thing when it finds that it hasn't received an editor
widget.

You could create an empty placeholder widget in the createEditor()
method, call QColorDialog.getColor() with the existing color from the
model in setEditorData(), record the color returned by the dialog in
some internal instance variable, and finally set the data in the model
when setModelData() is called:

class ColorProperty(Property):
...
def createEditor(self, parent, option, index):
return QtGui.QWidget(parent)
def setEditorData(self, editor, index):
self.color = QtGui.QColorDialog.getColor(
index.model().getObjectData(self.name()))
def setModelData(self, editor, model, index):
if self.color.isValid():
index.model().setObjectData(self.name(), self.color)
thanks for tip, i'll check it how it works.
...

I find it strange that you have to triple-click to edit any of the
items in your example. Do you see the same behaviour?
oh, this is default Qt behavoiur: first click selects row, second select
editor (for ColorProperty, IntProperty & StringProperty you can now
change the value) but third click is required only for properties w/
QCombobox editor (EnumProperty & BooleanProperty) ...

skink
>
David
Aug 30 '06 #3
Skink wrote:
David Boddie wrote:
I find it strange that you have to triple-click to edit any of the
items in your example. Do you see the same behaviour?
oh, this is default Qt behavoiur: first click selects row, second select
editor (for ColorProperty, IntProperty & StringProperty you can now
change the value) but third click is required only for properties w/
QCombobox editor (EnumProperty & BooleanProperty) ...
It seemed that, even if the row was already selected, it took more than
a double click to start editing. I'll have to take another look at it.

David

Aug 30 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Perttu Pulkkinen | last post by:
Hi all freaks! I have been thinking hard, what would be good solution for a straight-forward content management. I want to forget polls and forms etc.. and concentrate first only on different...
4
by: Adam Knight | last post by:
Hi all, I am using a dreamweaver template for a web app i am working on. Each time i update the template my page directives at the top of the associated pages gets removed. Anyone had...
1
by: shane.external | last post by:
I'm having trouble using Py2exe with a PyQT-based python project. Or possibly I'm having a problem with PyQT and Py2exe makes it apparent. Whichever it is, I run into trouble with importing QtCore...
2
by: Harshad | last post by:
Hi, I'm writing a program using Python 2.4 and PyQt4. The aim is to implement drag and drop from filesystem and display a list of files dragged on to the listWidget. This function will later...
3
by: Tina I | last post by:
I'm trying to 'convert' my self from Qt3 to Qt4 (it rocks!) and one thing seem strange: With Qt3 I usually did "from qt import *", but this does not seem to work with Qt4. I have to use "from...
25
by: Daniel Jonsson | last post by:
So, I've reached the point where my building pipeline tools actually needs to be used by other people in my company. By this reason I actually need to think about the usability, and I've come to...
2
by: AngelOfDarkness | last post by:
Hi guys, unfortunately I am pretty new to Python and Qt and all that. Well, I managed to successfully program a little stuff for my work (computational neuroscientist... no comment please), using...
5
by: Mel | last post by:
I am currently porting an SQL centered Visual Basic application to run on Linux, Python, and Qt4. Currently I am stumped on changing row colors in the QTableView widget. My test code is based on...
2
by: jiang.haiyun | last post by:
Hi, I am having some serious problems with PyQT4, when i run pyqt script, I always get 'Segmentation fault'. the script is simple: ====================== %less qttest.py from PyQt4 import...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.