PySide Pitfalls: Difference between revisions
No edit summary |
No edit summary |
||
(9 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
[[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 | * 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), | <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() == | |||
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. | |||
This means that '''the following code won't work''': | |||
<code> | |||
def on_signal(*args): | |||
print args | |||
print QtCore.QObject.sender() # THIS DOES NOT 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: | ||
<code> | |||
class Listener(QtCore.QObject): | |||
@QtCore.Slot() | |||
def on_signal(self, *args): | |||
print args | |||
print self.sender() | |||
listener = Listener() | |||
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)