[PyKDE] Small database application - best way?

Sibylle Koczian Sibylle.Koczian at T-Online.de
Mon Nov 27 08:50:00 GMT 2006

Very sorry: that should have gone to the list!


"David Boddie" <david at boddie.org.uk> schrieb:
> On 21 Nov 2006 10:29 GMT, Sibylle Koczian wrote:
> >"David Boddie" <david at boddie.org.uk> schrieb:
> >> Have you put the QTableView in a layout, or did you use QMainWindow for
> >> the window and set the QTableView as the central widget?
> >> 
> >
> >Put in a layout.
> If the QTableView is in a layout with other controls, you may need to make
> sure that it has a larger stretch factor than they do, to make it as large
> as possible. It may be the case that resizing the main window is the only
> way to give the table more space if the other controls also demand space
> from the layout system.

Begins to look like it; adding a stretch factor didn't help. But this isn't really important, I'll get back to it after solving all the other problems. I just thought I'd made some quite simple error, easily visible to anybody with more experience.

> An alternative is to try to change the widths of the rows and columns as
> displayed in the table.

That doesn't seem to alter the geometry of the viewport. 

Now back to problems that can't simply be worked around by a little dragging:

I connected the model in sqlcursorview.py with my database. That worked well, as long as I didn't try to make the model editable. To this end I implemented flags and setData:

def flags(self, index):
    flags = QtCore.QAbstractItemModel.flags(self, index)
    if index.column() in (0, 3, 4):
        flags |= QtCore.Qt.ItemIsEditable
    return flags

def setData(self, index, value, role):
    if role != QtCore.Qt.EditRole:
        return False
    if index.column() == 0:
        self._resultRows[index.row()][0] = value.toString()
    elif index.column() in (3, 4):
        self._resultRows[index.row()][index.column()] = int(value.toString())
        return False
    self.emit(QtCore.SIGNAL('dataChanged'), index, index)
    return True

Then I put the view and some buttons into a subclass of QWidget and added a small function to handle the 'dataChanged' signal:

In the __init__ method of the QWidget subclass:

             QtCore.SIGNAL('dataChanged(const QModelIndex &, '
                           'const QModelIndex &)'),

def ausgeben(self, startindex, endindex):
    print 'Daten geändert: Zeile %d, Spalte %d' % (startindex.row(),
    print 'Bis Zeile %d, Spalte %d' % (endindex.row(), endindex.column())

The data in column 0 are date values, in column 3 and 4 integer values.

This doesn't work as expected:

The method "ausgeben" is never called.

Double clicking, pressing F2 or Enter in a cell in one of the editable columns doesn't select the text of this cell, as it does in the example programs with editable models. Instead it erases the text completely. Not helpful, if a small typo should be corrected, a date altered by one day or similar small changes are necessary.

This last looks like a problem with the used delegate class. But the view is a standard QTableView, that should use a QItemDelegate, and the "data" method of the model changes everything to a unicode object and then to QVariant. It's the original method from the EuroPython example program. So that should work "out of the box", shouldn't it?

And a question: how can I convert the QVariant in column 0 to a Python datetime.date object, when I put it back into self._resultRows?

Thank you,

Dr. Sibylle Koczian 
Fasanenstrasse 12 
D-82293 Mittelstetten 

More information about the PyQt mailing list