PySide Pitfalls: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Format)
m (Added indentation to clarify the examples.)
Line 21: Line 21:
<code>
<code>
class MyStuff(object):
class MyStuff(object):
# …
  # …
def animate_stuff(self, target):
  def animate_stuff(self, target):
animation = QtCore.QPropertyAnimation(target, 'rotation')
      animation = QtCore.QPropertyAnimation(target, 'rotation')
animation.setDuration(700)
      animation.setDuration(700)
animation.setEasingCurve(QtCore.QEasingCurve.OutSine)
      animation.setEasingCurve(QtCore.QEasingCurve.OutSine)
animation.setEndValue(100)
      animation.setEndValue(100)
animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
      animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
</code>
</code>


Line 34: Line 34:
<code>
<code>
class MyStuff(object):
class MyStuff(object):
# …
  # …
def animate_stuff(self, target):
  def animate_stuff(self, target):
animation = QtCore.QPropertyAnimation(target, 'rotation', target)
      animation = QtCore.QPropertyAnimation(target, 'rotation', target)
# …
      # …
</code>
</code>


Line 50: Line 50:
<code>
<code>
def on_signal(*args):
def on_signal(*args):
print args
  print args
print QtCore.QObject.sender() # THIS DOES NOT WORK!
  print QtCore.QObject.sender() # THIS DOES NOT WORK!


a.someSignal.connect(on_signal)
a.someSignal.connect(on_signal)
Line 60: Line 60:
<code>
<code>
class Listener(QtCore.QObject):
class Listener(QtCore.QObject):
@QtCore.Slot()
  @QtCore.Slot()
def on_signal(self, *args):
  def on_signal(self, *args):
print args
      print args
print self.sender()
      print self.sender()


listener = Listener()
listener = Listener()
a.someSignal.connect(listener.on_signal)
a.someSignal.connect(listener.on_signal)

Revision as of 13:05, 28 March 2016


English 日本語


This Wiki page lists common pitfalls that you might step into when starting out with PySide development. If you experience some "Oh!" moment while developing your apps using PySide, please document the issue here.

References

If a QObject falls out of scope in Python, it will get deleted. You have to take care of keeping a reference to the object:

  • Store it as an attribute of an object you keep around, e.g.
    self.window = QMainWindow()
    
  • Pass a parent QObject to the object's constructor, so it gets owned by the parent

This does not work:

class MyStuff(object):
   # …
   def animate_stuff(self, target):
      animation = QtCore.QPropertyAnimation(target, 'rotation')
      animation.setDuration(700)
      animation.setEasingCurve(QtCore.QEasingCurve.OutSine)
      animation.setEndValue(100)
      animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)

The reason for this is that the animation will get deleted at the end of

animate_stuff()

, so it does not really get the chance to do anything. In the case of animations (which usually have a target QObject), it's a good idea to make it a child of the parent by giving the parent as last argument to the constructor:

class MyStuff(object):
   # …
   def animate_stuff(self, target):
      animation = QtCore.QPropertyAnimation(target, 'rotation', target)
      # …

This will work, because the animation reference is now owned by "target". Another option is to save the animation as an attribute of the object (using "self.animation = …"). This way, the reference to the animation is kept around as long as the object that has the attribute (if it does not get deleted manually before). Be aware that overwriting the attribute (e.g. with another animation while the first animation is still running) will again cause all references for the object to be removed, therefore deleting the object again.

QtCore.QObject.sender()

If you want to get the object that emitted a signal, you can do so using

QtCore.QObject.sender()

, although you should really think twice before using it (see the API docs of QObject for details). If you really, really decide that you have to use it, be aware that right now, you cannot call it as a static method, but only from within a QObject slot.

This means that the following code won't work:

def on_signal(*args):
   print args
   print QtCore.QObject.sender() # THIS DOES NOT WORK!

a.someSignal.connect(on_signal)

To achieve the same effect, you have to create a QObject subclass with a Slot and access sender() as a member method of your object, like this:

class Listener(QtCore.QObject):

  @QtCore.Slot()
  def on_signal(self, *args):
     print args
     print self.sender()

listener = Listener() a.someSignal.connect(listener.on_signal)