--- author: '' category: '' date: 2010/02/19 22:07 description: '' link: '' priority: '' slug: BB873 tags: open source, programming, pyqt, python, qt title: The aha! moment type: text updated: 2010/02/19 22:07 url_type: '' --- I had a small task today in `Marave `_. The goal was: 1. Fade in a widget 2. Set a variable 3. Fade in another one It's important that things are done *in that order* and it's also important that the app remains interactive. And here's the code to do that (simplified): .. code-block:: python def fadein(thing, target=1., thendo=None): """ * thing is a QWidget * thing.proxy is a QGraphicsWidget * thendo is callable * target is the desired opacity """ thing.anim=QtCore.QPropertyAnimation(thing.proxy, "opacity") thing.anim.setDuration(200) thing.anim.setStartValue(thing.proxy.opacity()) thing.anim.setEndValue(target) thing.anim.start() thing.anim.finished.connect(thing.anim.deleteLater) if thendo: thing.anim.finished.connect(thendo) And this is how you use it: .. code-block:: python def later(): avar=avalue fadein(widget2) fadein(widget1, thendo=later) Isn't that *lovely*? Having functions as first class objects means I can just take ``later`` as a closure, along with ``widget2`` and ``avar``, which need only be defined in the local scope, and the call chain will work just as I wanted! Yes, many other languages can do this, and in Javascript it's one of the most common tricks, but consider that PyQt is a wrapper for a C++ library! I think this kind of usage shows the real added value PyQt brings to the table, it's not just that python avoids the boring compiles, or that you have the awesome standard library to use, but that the *language itself* enables you to do things that are not practical in C++. In C++ the only way I can think of is creating a slot that's the equivalent of later, then chaining the signals... which means that this throwaway ``later`` becomes part of the interface of a class! I would have to define ``later`` somewhere else on the file, separate from its only usage (maybe even inlined in the header file). Even then, that's not equivalent: avalue may be something that was only avalable before the first call to fadein, (for example, the time of the first fadein): I would have to create a place to store it, make it reachable by ``later``... and wht happens if you try to do this again while the first fadein is in progress?... it gets hairy. Programming is like a slap in the face sometimes... you realize that things you use without even noticing are far from trivial. So, remember young padawan: you can choose you tools. Choose wisely.