[PyQt] unexpected behavior from winId() and QSpacerItem

Brian Parma freecode at cox.net
Tue Aug 19 09:03:33 BST 2008


Ok, so I was making a simple widget that had a little 32x32 png image 
that you can pick up and move around.  I do this by setting the mouse 
cursor to a pixmap cursor of the image when mousePressEvent is 
triggered, and reverting back when mouseReleaseEvent is triggered.  I 
also want to track the mouse with mouseMoveEvent for later 
functionality.  For the functionality I want, the mouse needs to 
continue to be tracked when it leaves the widget/window (and hopefully 
keeps the icon).  This was easier to get working than I had thought, but 
when I started adding functionality and incorporated it into a window I 
ran into some strange behavior.  If I have my widget in a gridLayout 
with a QSpacerItem with a QSizePolicy.Expanding property and also call 
winId() for my widget, the tracking/cursor break when the mouse goes out 
of the window.  The behavior is even different I move the mouse out the 
top vs. out the sides and bottom, as the former doesn't even resume 
tracking when the mouse comes back onto the window. 

The appended code reproduces the behavior (I'm using PyQt4.4.3 and 
Python2.5.2, on WindowsXP Pro). 

If you comment out the call to self.winId(), than the code works as 
expected.  Also, if you leave the call to self.winId() but remove the 
",QtGui.QSizePolicy.Expanding" from the QSpacerItem constructor the code 
works correctly.  It seems that having both of them breaks something.  
Is this a Bug, or am I just missing something?



from PyQt4 import QtGui, QtCore
import sys

class Drag(QtGui.QLabel):
    def __init__(self, parent=None):
        QtGui.QLabel.__init__(self, parent)
        self.image = QtGui.QPixmap('dead.png')
        self.wfc = QtGui.QCursor(self.image)
        self.setPixmap(self.image)
        self.winId()
       
    def mousePressEvent(self, event):
        print 'set'
        self.setPixmap(QtGui.QPixmap())
        self.setCursor(self.wfc)
        event.accept()
       
    def mouseMoveEvent(self, event):
        print event.pos()
        event.accept()

    def mouseReleaseEvent(self, event):
        print 'rel'
        self.setCursor(QtCore.Qt.ArrowCursor)
        self.setPixmap(self.image)
        event.accept()
 

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = QtGui.QWidget()
    lay = QtGui.QGridLayout(win)
    dw = Drag(win)
    lay.addWidget(dw)
    lay.addItem(QtGui.QSpacerItem(13,20,QtGui.QSizePolicy.Expanding), 1, 1)
    win.show()
    win.resize(200,200)
   
    app.exec_()

-------------- next part --------------
from PyQt4 import QtGui, QtCore
import sys

class Drag(QtGui.QLabel):
    def __init__(self, parent=None):
        QtGui.QLabel.__init__(self, parent)
        self.image = QtGui.QPixmap('dead.png')
        self.wfc = QtGui.QCursor(self.image)
        self.setPixmap(self.image)
        self.winId()
        
    def mousePressEvent(self, event):
        print 'set'
        self.setPixmap(QtGui.QPixmap())
        self.setCursor(self.wfc)
        event.accept()
        
    def mouseMoveEvent(self, event):
        print event.pos()
        event.accept()

    def mouseReleaseEvent(self, event):
        print 'rel'
        self.setCursor(QtCore.Qt.ArrowCursor)
        self.setPixmap(self.image)
        event.accept()
  

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = QtGui.QWidget()
    lay = QtGui.QGridLayout(win)
    dw = Drag(win)
    lay.addWidget(dw)
    lay.addItem(QtGui.QSpacerItem(13,20,QtGui.QSizePolicy.Expanding), 1, 1)
    win.show()
    win.resize(200,200)
    
    app.exec_()


More information about the PyQt mailing list