PDA

View Full Version : PyQt QTimer problem { FIXED }



WinchellChung
1st March 2008, 16:50
I had an annoying problem with my PyQt app, but I fixed it. I present it here so other newbies can avoid making the same mistake.

My PyQt app had a class derived from QGraphicsScene. The scene adds about a hundred QPixMaps to itself.

Trouble was, when the program exited, I got about a hundred of the following error messages:

QObject::startTimer: QTimer can only be used with threads started with QThread

As a matter of fact, there were the same number of error messages as the number of QPixMaps.

After reading the PyQt API, I found the solution. The API stated:

QGraphicsScene.__init__ (self, QObject parent = None)
The parent argument, if not None, causes self to be owned by Qt instead of PyQt.

Yes, when I checked, I discovered that I had not passed a parent argument to the init function of my QGraphicsScene sub-class. When I passed "self", the problem vanished.

Why did this happen? A note on the PyQt forum said the problem sometimes happens when Python's garbage collection deletes items in the wrong order.

This code fragment illustrates the problem:


from PyQt4 import QtCore, QtGui

class ModelHexMap(QtGui.QGraphicsScene):

def __init__(self, tilePath, mapPath, parent=None):
QtGui.QGraphicsScene.__init__(self, parent)
self.commonInit(tilePath, mapPath)

def commonInit(tilePath, mapPath):
# make calls to self.addPixmap()

class MyForm(QtGui.QMainWindow):

def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)

# the following causes the error
self.ModelHexMap = ModelHexMap("game.til", "game.map")
# this is the correct way
self.ModelHexMap = ModelHexMap("game.til", "game.map", self)

if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())