[PyQt] QAbstractItemModel.setData() and emit
Tom Brown
brown at esteem.com
Thu Jul 19 20:54:25 BST 2007
On Thursday 19 July 2007 10:41, Andreas Pakulat wrote:
> On 19.07.07 09:14:20, Tom Brown wrote:
> > On Wednesday 18 July 2007 15:40, Andreas Pakulat wrote:
> > > On 18.07.07 14:58:11, Tom Brown wrote:
> > > > Hi,
> > > >
> > > > I am using PyQt4 with Qt 4.2.3. I have subclassed QAbstractItemModel
> > > > to create a custom model for a custom combobox. I have overridden the
> > > > setData() method and keep getting this error:
> > > >
> > > > TypeError: invalid result type from ECBModel.setData()
> > > >
> > > > When I remove the call to emit(), the error goes away. Here is my
> > > > setData() method:
> > >
> > > You don't need to emit dataChanged in setData, you only need to emit
> > > that signal if you change data in custom methods.
> >
> > The documentation says you need to emit dataChanged() if you reimplement
> > the setData() method.
> >
> > "Note that the dataChanged() signal must be emitted explicitly when
> > reimplementing this function."
>
> Hmm, my Qt4.3 docs only say it should be emitted, not that it has to be
> emitted. Anyway, basically you're right and I was wrong (looks like my
> last model impl. is quite some time ago)
>
> > > Also note: setData shouldn't alter the number of rows or columns in the
> > > model, it should only change the data of an existing "cell". If you
> > > want to add a row/column you should use insertRows/Columns (and
> > > eventually re-implement them).
> >
> > Well, I reimplemented a few required methods like index() and parent().
> > The error stopped showing up. However, the combobox never shows a value
> > even though there are items in the list. Any ideas on that?
>
> Not without some example code. Up-to-date PyQt snapshots contain a
> python port of the ModelTest from Qt Labs, it can be used to test wether
> your model conforms to the assumptions that views make about it.
Here's my model. I am running queries against a PostgreSQL database. I'll try
out the ModelTest. Thanks.
class ECBModel(QAbstractItemModel):
def __init__(self, dbInfo, sql, parent=None):
QAbstractItemModel.__init__(self, parent)
self.dbInfo = dbInfo
self.sql = sql
self.insertSQL = None
self.queryData = []
self.sequence = None
self.refresh()
def columnCount(self, parent):
return 2
def currentID(self, currentText):
for row in self.queryData:
if row[1] == currentText:
return row[0]
return None
def data(self, index, role):
if not index.isValid():
return QVariant()
if role != Qt.DisplayRole:
return QVariant()
if not self.queryData:
return QVariant()
if not (index.row() < len(self.queryData)):
return QVariant()
return QVariant(self.queryData[index.row()][index.column()])
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def getIDFromText(self, text):
return self.currentID(text)
def index(self, row, column, parent):
data = self.queryData[row][column]
return self.createIndex(row, column, data)
def insertRows(self, row, count, parent):
self.beginInsertRows(parent, row - 1, row - 1)
self.queryData.insert(row, [0, ''])
self.endInsertRows()
return True
def insertRecord(self, value):
if self.insertSQL:
connection, cursor = getPgCursor(self.dbInfo)
try:
try:
id = getNextVal(cursor, self.sequence)
sql = self.insertSQL % (id, value)
cursor.execute(sql)
connection.commit()
finally:
connection.close()
except:
return (0, '')
return id, value
return (0, '')
def parent(self, index):
return QModelIndex()
def refresh(self):
self.queryData = []
connection, cursor = getPgCursor(self.dbInfo)
try:
cursor.execute(self.sql)
rows = cursor.fetchall()
for row in rows:
self.queryData.append([row[0], row[1]])
connection.commit()
finally:
connection.close()
def rowCount(self, parent):
return len(self.queryData)
def setData(self, index, value, role):
id, value = self.insertRecord(str(value.toString()))
if id:
data = index.internalPointer()
data[0] = id
data[1] = value
self.emit(SIGNAL('dataChanged(const QModelIndex &, '
'const QModelIndex &)'), index, index)
return True
return False
def setID(self, id):
rowCount = 0
for row in self.queryData:
if row[0] == id:
return rowCount
rowCount += 1
return None
def setInsertSQL(self, sql):
self.insertSQL = sql
More information about the PyQt
mailing list