Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

PySide Pitfalls: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
 
(9 intermediate revisions by 5 users not shown)
Line 1: Line 1:
'''English''' [[PySide-Pitfalls-Japanese|日本語]]


=PySide Pitfalls=


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.
[[Category:PySide]]


==References==
{| class="wikitable"
|-
| style="background: #ff6961;text-align: center;"| Attention
|-
| This is a page dedicated to PySide (Qt4). For recent development on PySide2 (Qt5) and PySide6 (Qt6) refer to [[Qt for Python]]
|}
 
'''English''' [[Pyside-Pitfalls-japanese|日本語]]
 
 
 
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:
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. <code>self.window = QMainWindow()</code>
* Store it as an attribute of an object you keep around, e.g. <code>self.window = QMainWindow()</code>
* Pass a parent QObject to the object’s constructor, so it gets owned by the parent
* Pass a parent QObject to the object's constructor, so it gets owned by the parent


'''This does not work:'''
'''This does not work:'''


The reason for this is that the animation will get deleted at the end of <code>animate_stuff()</code>, 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:
<code>
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)
</code>
 
The reason for this is that the animation will get deleted at the end of <code>animate_stuff()</code>, 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:
 
<code>
class MyStuff(object):
  # …
  def animate_stuff(self, target):
      animation = QtCore.QPropertyAnimation(target, 'rotation', target)
      # …
</code>
 
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() ==


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.
If you want to get the object that emitted a signal, you can do so using <code>QtCore.QObject.sender()</code>, 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.


==QtCore.QObject.sender()==
This means that '''the following code won't work''':


If you want to get the object that emitted a signal, you can do so using <code>QtCore.QObject.sender()</code>, although you should really think twice before using it (see the <span class="caps">API</span> 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.
<code>
def on_signal(*args):
  print args
  print QtCore.QObject.sender() # THIS DOES NOT WORK!


This means that '''the following code won’t work''':
a.someSignal.connect(on_signal)
</code>


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:
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:


===Categories:===
<code>
class Listener(QtCore.QObject):
  @QtCore.Slot()
  def on_signal(self, *args):
      print args
      print self.sender()


* [[:Category:LanguageBindings|LanguageBindings]]
listener = Listener()
** [[:Category:LanguageBindings::PySide|PySide]]
a.someSignal.connect(listener.on_signal)

Latest revision as of 10:34, 24 February 2022


Attention
This is a page dedicated to PySide (Qt4). For recent development on PySide2 (Qt5) and PySide6 (Qt6) refer to Qt for Python

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)