[PyKDE] strange problems with lxml and PyQt4
Andreas Pakulat
apaku at gmx.de
Thu Jan 12 17:21:31 GMT 2006
On 12.01.06 09:48:24, Phil Thompson wrote:
> You need to post a short, but complete, example that demonstrates the problem.
No Problem, is attached including a sample xml file.
> When people select code fragments to post, but can't find the error, its
> usually because they are looking in the wrong place.
Or they don't have the slightest idea what could cause an error like
the posted one and therefore cannot do more than look at the traceback.
To reproduce just execute the script and select the entry then try to
add a new entry (the upper button) or remove it (the lower one). Adding
a new entry when nothing is selected works.
Andreas
--
Tonight's the night: Sleep in a eucalyptus tree.
-------------- next part --------------
<?xml version="1.0" encoding="utf-8"?>
<pictureFormats xmlns="testns">
<pictureFormat>Widescreen 1:2,35</pictureFormat>
</pictureFormats>
-------------- next part --------------
from PyQt4 import QtGui, QtCore
from lxml import etree
import sys
moviedbns = "testns"
def buildQName(ns, name):
return "{%s}%s" % (ns, name)
def buildElement(parent, elementType):
return etree.SubElement(parent, buildQName(moviedbns, elementType))
modeldata = {
'elementname':'pictureFormat',
'items':
[
{
'elemattr' : 'format',
'variantmethod' : 'toString',
'header' : QtCore.QT_TR_NOOP('Format')
},
]
}
class Ui_PictureFormatWidget(object):
def setupUi(self, PictureFormatWidget):
PictureFormatWidget.setObjectName("PictureFormatWidget")
PictureFormatWidget.resize(QtCore.QSize(QtCore.QRect(0,0,298,120).size()).expandedTo(PictureFormatWidget.minimumSizeHint()))
self.vboxlayout = QtGui.QVBoxLayout(PictureFormatWidget)
self.vboxlayout.setMargin(0)
self.vboxlayout.setSpacing(6)
self.vboxlayout.setObjectName("vboxlayout")
self.groupBox = QtGui.QGroupBox(PictureFormatWidget)
self.groupBox.setObjectName("groupBox")
self.hboxlayout = QtGui.QHBoxLayout(self.groupBox)
self.hboxlayout.setMargin(6)
self.hboxlayout.setSpacing(6)
self.hboxlayout.setObjectName("hboxlayout")
self.pictureFormats = QtGui.QTableView(self.groupBox)
self.pictureFormats.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
self.pictureFormats.setObjectName("pictureFormats")
self.hboxlayout.addWidget(self.pictureFormats)
self.vboxlayout1 = QtGui.QVBoxLayout()
self.vboxlayout1.setMargin(0)
self.vboxlayout1.setSpacing(6)
self.vboxlayout1.setObjectName("vboxlayout1")
spacerItem = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding)
self.vboxlayout1.addItem(spacerItem)
self.addPictureFormat = QtGui.QPushButton(self.groupBox)
self.addPictureFormat.setIcon(QtGui.QIcon(":/widgets/images/add_64x64.png"))
self.addPictureFormat.setObjectName("addPictureFormat")
self.vboxlayout1.addWidget(self.addPictureFormat)
self.removePictureFormat = QtGui.QPushButton(self.groupBox)
self.removePictureFormat.setIcon(QtGui.QIcon(":/widgets/images/remove_64x64.png"))
self.removePictureFormat.setObjectName("removePictureFormat")
self.vboxlayout1.addWidget(self.removePictureFormat)
spacerItem1 = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding)
self.vboxlayout1.addItem(spacerItem1)
self.hboxlayout.addLayout(self.vboxlayout1)
self.vboxlayout.addWidget(self.groupBox)
self.retranslateUi(PictureFormatWidget)
def tr(self, string):
return QtGui.QApplication.translate("PictureFormatWidget", string, None, QtGui.QApplication.UnicodeUTF8)
def retranslateUi(self, PictureFormatWidget):
PictureFormatWidget.setWindowTitle(self.tr("Form"))
self.groupBox.setTitle(self.tr("PictureFormats"))
class GeneralTableModel(QtCore.QAbstractItemModel):
"""
Customizable Model for Tables and Lists being build on a list of ElementTree Elements
Customization is provided in the modeldata initialization parameter for the
list given as list parameter. The modeldata needs to be a dictionary that has
an items and an elementname entry.
elementname contains the XML Element name for new data items
items contains a list of dictionaries resembling the columns of the table/list.
Each dictionary in the list needs to provide 3 entries:
elemattr specifies the attribute that this column should work on
variantmethod specifies which QVariant "toXXX" method should be used for conversion
header contains the string that should be display in the header
"""
def __init__(self, list, modeldata, parent = None):
QtCore.QAbstractItemModel.__init__(self, parent)
self.datalist = list
self.items = modeldata['items']
self.elementname = modeldata['elementname']
def data(self, index, role):
if not index.isValid() or \
( role != QtCore.Qt.DisplayRole and role != QtCore.Qt.EditRole ) or \
not self.datalist:
return QtCore.QVariant()
if index.row() >= 0 and index.row() < self.rowCount(index.parent()) and \
index.column() < self.columnCount(index) and index.column() >= 0:
data = getattr(self.datalist[index.row()], self.items[index.column()]['elemattr'])
return QtCore.QVariant(data)
return QtCore.QVariant()
def headerData( self, column, orientation, role = QtCore.Qt.DisplayRole):
if orientation == QtCore.Qt.Horizontal:
return QtCore.QVariant(self.items[column]['header'])
return QtCore.QVariant()
def index(self, row, column, parent = QtCore.QModelIndex()):
if parent == QtCore.QModelIndex() and row >= 0 and row < self.rowCount(parent) and self.datalist:
return self.createIndex(row, column)
return QModelIndex()
def rowCount(self, parent = QtCore.QModelIndex()):
if parent == QtCore.QModelIndex() and self.datalist:
return len(self.datalist)
return 0
def columnCount(self, index = QtCore.QModelIndex()):
return len(self.items)
def flags(self, index):
if not index.isValid():
return QtCore.Qt.ItemIsEnabled
return QtCore.QAbstractItemModel.flags(self, index) | QtCore.Qt.ItemIsEditable
def insertRows(self, row, count, parent = QtCore.QModelIndex()):
if not self.datalist:
return False
self.beginInsertRows( parent, row, count+row-1)
for i in range(0, count):
self.datalist.insert(row+i, buildElement(self.datalist, self.elementname))
self.endInsertRows()
return True
def removeRows(self, row, count, parent = QtCore.QModelIndex()):
if not self.datalist or len(self.datalist) < count:
return False
self.beginRemoveRows(QtCore.QModelIndex(), row, count+row-1)
lst = self.datalist
del lst[row:row+count]
self.endRemoveRows()
return True
def setData(self, index, data, role = QtCore.Qt.EditRole):
if self.datalist and index.isValid() and role == QtCore.Qt.EditRole and \
index.row() >= 0 and index.row() < self.rowCount(index.parent()) and \
index.column() >= 0 and index.column() < self.columnCount(index):
qvariantfunc = getattr(QtCore.QVariant, self.items[index.row()]['variantmethod'])
setattr(self.datalist[index.row()], self.items[index.column()]['elemattr'], qvariantfunc(data))
return True
return False
class PictureFormatWidget(QtGui.QWidget, Ui_PictureFormatWidget):
def __init__(self, parent = None):
QtGui.QWidget.__init__(self, parent)
Ui_PictureFormatWidget.__init__(self)
self.setupUi(self)
self.pictureFormats.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch)
self.connect(self.removePictureFormat, QtCore.SIGNAL('clicked()'), self.on_removePictureFormat_clicked)
self.connect(self.addPictureFormat, QtCore.SIGNAL('clicked()'), self.on_addPictureFormat_clicked)
def setPictureFormatList( self, list ):
model = GeneralTableModel(list, modeldata, self)
old = self.pictureFormats.model()
self.pictureFormats.setModel(model)
if old:
old = None
def on_removePictureFormat_clicked(self):
list = self.pictureFormats.selectionModel().selectedIndexes()
model = self.pictureFormats.model()
for index in list:
model.removeRows(index.row(), 1, index.parent())
def on_addPictureFormat_clicked(self):
self.pictureFormats.model().insertRows(self.pictureFormats.model().rowCount(), 1)
class PictureFormat(etree.ElementBase):
"""Stores PictureFormat information"""
def format(self):
return str(self.text)
def setFormat(self, format):
self.text = format
format = property(format, setFormat)
def main():
myns = etree.Namespace(moviedbns)
myns['pictureFormat'] = PictureFormat
app = QtGui.QApplication(sys.argv)
tree = etree.parse("filmdb.xml")
doc = tree.getroot()
widget = PictureFormatWidget()
widget.setPictureFormatList(doc)
widget.show()
return app.exec_()
if __name__ == "__main__":
sys.exit(main())
More information about the PyQt
mailing list