[PyQt] Signal filtering based on arguments

Florian Bruhin me at the-compiler.org
Wed Oct 8 07:20:42 BST 2014


Hi,

I have an issue which I don't really know to solve properly, maybe
someone has an idea here.

My application has a configuration structured into sections and
options. The user can change the config from inside the application,
and everything should update/reinitialize correctly on a change, so no
restart of the application is needed.

I have a global Config object which stores the configuration and has a
"changed" signal, with the section/option as a parameter.

Now I have a lot of "on_config_changed" slots in many different
objects, and most of the time these are only interested in a few
options - only if these are changed they have to take action (for
example call setStyleSheet again because a configured color/font
changed).

My original solution was simply having these slots, connecting them in
a central place (where I create the config object) and checking inside
each slot if it is interested in the event.

As this was rather unpractical, I tried switching to a solution where
every object calls  `config.on_change(section, option, callback)`. The
config module then saves a (section, option, callback) tuple in a list
of callback handlers, and calls the appropriate callbacks on a change.

The implementation is here:
https://github.com/The-Compiler/qutebrowser/blob/b49b227c0d1ba7a580749f1572729311263ba299/qutebrowser/config/config.py#L46-L70

Now the problem is this keeps references to methods of objects which
might get deleted by Qt at some point (for example when I open a
new window, the change handlers get registered, and when I close it
again the window is deleted but the change handler is still present).

I tried passing the underlying object to on_change which then uses the
`destroyed` signal emitted by Qt to remove the handler if the object
gets destroyed, but for some reason I still got RuntimeError's because
"self" wasn't existent anymore in the change handlers.

At this point I think reverting back to my original approach would be
the better idea :D

Some ideas I had to make it more bearable:

- Use a decorator for the on_config_changed slots to easily check if
  it's a `changed`-signal we're interested in and return if not.

- Connect the slots directly in __init__ of the consumer objects
  instead of a central place.

Does anyone else have a better idea I've not thought of yet?

Florian

-- 
http://www.the-compiler.org | me at the-compiler.org (Mail/XMPP)
             GPG 0xFD55A072 | http://the-compiler.org/pubkey.asc
         I love long mails! | http://email.is-not-s.ms/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20141008/c11792a6/attachment.sig>


More information about the PyQt mailing list