[PyQt] Segfault when activating items in a view, more info
Hans-Peter Jansen
hpj at urpla.net
Mon Aug 9 12:31:15 BST 2010
On Monday 09 August 2010, 12:20:36 Andreas Pakulat wrote:
> On 09.08.10 12:06:57, Hans-Peter Jansen wrote:
> > Hi Peter,
> >
> > while not of big help, here are a few more details and the backtrace.
> >
> > Qt 4.6.3, sip 4.10.5, PyQt4 4.7.4.
> >
> > On Monday 09 August 2010, 09:42:05 peter at lohmanders.se wrote:
> > > Yes, the connect signal had the wrong signature, but that doesn't
> > > matter. I do not get a warning when trying to connect invalid
> > > signals, but even if I have no activated-signal connected, the darn
> > > thing still segfaults when I double click any cell.
> >
> > Well, even with a correct signal, this crashes (after executing the
> > signal handler):
> >
> > import sys
> > from PyQt4 import QtGui, QtCore
> >
> > class TestModel(QtCore.QAbstractTableModel):
> >
> > def headerData(self, section, orientation, role =
> > QtCore.Qt.DisplayRole):
> > return QtCore.QVariant("a")
> >
> > def data(self, index, role = QtCore.Qt.DisplayRole):
> > if (role == QtCore.Qt.DisplayRole
> > and index.isValid()
> > and 0 <= index.row() < 2
> > and 0 <= index.column() < 2):
> > return QtCore.QVariant("t")
> > return QtCore.QVariant()
> >
> > def columnCount(self, index):
> > return 2
> >
> > def rowCount(self, index):
> > return 2
>
> If you use this model on a treeview you'll probably end up in an infinite
> tree size. The reason is that you're returning a child-count of 2 for
> each and every index (and the treeview is going to ask for the row-count
> of each toplevel entry). Try to add a check for index.isValid() and only
> return 2 if its not a valid index.
Yes, that did the trick. As Peter said, this is rather counterintuitive as
an table API, but anyway. For any descendants:
import sys
from PyQt4 import QtGui, QtCore
class TestModel(QtCore.QAbstractTableModel):
def headerData(self, section, orientation, role =
QtCore.Qt.DisplayRole):
return QtCore.QVariant("a")
def data(self, index, role = QtCore.Qt.DisplayRole):
if (role == QtCore.Qt.DisplayRole
and index.isValid()
and 0 <= index.row() < 2
and 0 <= index.column() < 2):
return QtCore.QVariant("t")
return QtCore.QVariant()
def columnCount(self, index):
if not index.isValid():
return 2
return 0
def rowCount(self, index):
if not index.isValid():
return 2
return 0
def onActivated():
print "activated"
if __name__ == "__main__":
app = QtGui.QApplication([])
win = QtGui.QMainWindow()
model = TestModel()
view = QtGui.QTreeView()
view.setModel(model)
view.setRootIsDecorated(False)
view.activated.connect(onActivated)
win.setCentralWidget(view)
win.show()
app.exec_()
BTW, this model reveals another issue: the focus can be set to all table
items by clicking with the mouse, but only to the left column items by
keyboard. Is that to be expected? Given, above is enough to implement a
read only table, shouldn't it handle keyboard navigation properly, too?
@Peter: now that you got a solution for free, how about returning something
by sticking this into the wiki: http://diotavelli.net/PyQtWiki
Cheers,
Pete
More information about the PyQt
mailing list