# Custom Signal/Slots with PythonQt

**URL:** <https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278>\
**Category:** Development\
**Tags:** python, qt\
**Created:** [June 25, 2018, 1:38pm UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278 "2018-06-25T13:38:25Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![mcfly3001](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mcfly3001/32/6437_2.png) [@mcfly3001](https://discourse.slicer.org/u/mcfly3001)\
**Post date:** [June 25, 2018, 1:38pm UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278/1 "2018-06-25T13:38:25Z")

</div>

Hi all,

the signal/slot system of Qt is a very helpful mechanism for implementing callbacks. I was wondering if I can create my own signals and slots with PythonQt but had no success so far.  
In other projects where I use e.g. pySide I can subclass from “QObject” and then define my custom signals which then can be connected to my callbacks. When searching in PythonQt threads I found a similar code snippet here:

[https://sourceforge.net/p/pythonqt/discussion/631393/thread/bbc98b8f/](https://sourceforge.net/p/pythonqt/discussion/631393/thread/bbc98b8f/)

Unfortunately I am not able to get a PythonQt.QtCore.QObject object in the Python version of Slicer. Is this some wanted restriction?  
If this is not possible, is there a similar mechansim available? As an example: I have an IGTL connection which receives data. Based on the data I want to update some UI elements. The connection class and the Widget class are two separate classes though. I am trying to keep the logic separated from the UI.

Thanks for any help!

---

<div class="post-metadata">

**Author:** ![jcfr](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jcfr/32/17825_2.png) [@jcfr](https://discourse.slicer.org/u/jcfr)\
**Post date:** [June 25, 2018, 11:54pm UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278/2 "2018-06-25T23:54:56Z")

</div>

> [@mcfly3001](#):
>
> Unfortunately I am not able to get a PythonQt.QtCore.QObject object in the Python version of Slicer. Is this some wanted restriction?

In addition of being available in the `PythonQt.QtXXX` namespace, for convenience, all qt objects are also imported in the `qt` namespace.

Any of these currently work:

```auto
import qt
qt.Signal("QVariant")

```

or

```auto
import PythonQt
PythonQt.QtCore.Signal("QVariant")

```

That said, `QObject` is not available. We should probably update the version of PythonQt bundled in Slicer. It is currently based on [r455](https://sourceforge.net/p/pythonqt/code/455/). More details here: [GitHub - commontk/PythonQt: CMake-ified version of PythonQt](https://github.com/commontk/PythonQt)

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [June 26, 2018, 7:05am UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278/3 "2018-06-26T07:05:25Z")

</div>

It would be good to know if PythonQt supports creating signals directly and if it does we can add it to Slicer. There are limits compared with PySide, but it gets better over time. Did you look at the [PythonQt page](http://pythonqt.sourceforge.net) and check with the folks there?

---

<div class="post-metadata">

**Author:** ![mcfly3001](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mcfly3001/32/6437_2.png) [@mcfly3001](https://discourse.slicer.org/u/mcfly3001)\
**Post date:** [June 26, 2018, 8:30am UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278/4 "2018-06-26T08:30:47Z")

</div>

Thanks for your suggestions. I reviewed the PythonQt page which says:

> QObject.emit to emit Qt signals from Python is not yet implemented but PythonQt allows to just emit a signal by calling it like a normal slot

So I will now try to create a signal and emit it directly as jcfr suggested. Just to be sure, would something like this work then?

```python
 import qt
 
 class ReceiverClass:
 
     new_parameters_received = qt.Signal("QVariant")
 
     def _on_reveive(self, params):
         new_parameters_received.emit(params)

 class UserInterface:
     
    def __init__ (self, receiver):
       receiver.new_parameters_received.connect(self._on_new_params)

    def _on_new_params(self, data):
        self._bt_foo.setText(data[0])
        ....

```

Thanks again!

---

<div class="post-metadata">

**Author:** ![mcfly3001](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mcfly3001/32/6437_2.png) [@mcfly3001](https://discourse.slicer.org/u/mcfly3001)\
**Post date:** [June 28, 2018, 12:33pm UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278/5 "2018-06-28T12:33:51Z")

</div>

Hi again,

I did some more tests and still have some problems using the signal-slot concept via Qt. To beginn with I forgot to mention that I was using the stable release of Slicer. Therefore, there was no qt.Signal or qt.Slot object available, only a qt.SIGNAL which would not work.

After updating to a nightly release version of Slicer, the qt.Signal and qt.Slot classes were available. I was still not able though to connect a simple signal with a slot. Everytime I try to connect, the whole application just crashes, e.g.:

```python
import qt

test_sig = qt.Signal("QVariant")

@qt.Slot("QVariant")
def test_slot(data):
    print(data)

test_sig.connect(test_slot)
test_sig.emit("Foo")

```

Other similar tries (e.g. without qt.Slot decorator) lead to a crash or a non-working connection. In the end I just tried to wrap the signal-slot connection into a class which derives from QWidget (since QObject is not available). This seems to solve the issue. The signal is connected and also correctly triggered.

It still though does not feel right to subclass from QWidget for every class that needs signal-slot feature. Therefore I might use an alternative solution, e.g. the PySignals module. Or are there any better proposals for me?

Thanks!

---

<div class="post-metadata">

**Author:** ![ihnorton](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/ihnorton/32/9_2.png) [@ihnorton](https://discourse.slicer.org/u/ihnorton)\
**Post date:** [June 28, 2018, 2:54pm UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278/6 "2018-06-28T14:54:42Z")

</div>

> [@jcfr](#):
>
> That said, `QObject` is not available. We should probably update the version of PythonQt bundled in Slicer. It is currently based on [r455](https://sourceforge.net/p/pythonqt/code/455/).

@jcfr I looked through the commits after r455, and didn’t see anything that was obviously related… I wonder if something from CTK is shadowing/removing QObject, because it is [registered](https://github.com/commontk/PythonQt/blob/patched-8/generated_cpp_56/com_trolltech_qt_core/com_trolltech_qt_core_init.cpp#L109) the same way as many other classes which _are_ available under `PythonQt.QtCore` in the repl (e.g. `QMimeData`).

---

<div class="post-metadata">

**Author:** ![PaoloZaffino](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/paolozaffino/32/81052_2.png) [@PaoloZaffino](https://discourse.slicer.org/u/PaoloZaffino)\
**Post date:** [May 25, 2020, 12:23pm UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278/7 "2020-05-25T12:23:23Z")

</div>

Hi all,  
I’m interested in emitting a signal and, if some object is registered on this “channel”, in receiving it.  
Any idea about which qt tool can I use?  
I also read [this](https://discourse.slicer.org/t/use-of-qt-signal-leads-to-a-crash-on-exit/8321) and I got a crash too.

Thanks a lot.  
Paolo

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 25, 2020, 12:57pm UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278/8 "2020-05-25T12:57:31Z")

</div>

We have signal/slot mechanism in Qt and observer mechanism in VTK, and you can implement custom plugin or callback mechanisms. These are all available to be used from both C++ and Python.

Probably the most universal way (that is available from all Slicer classes) is to observe/invoke custom modified events on a MRML node.

---

<div class="post-metadata">

**Author:** ![PaoloZaffino](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/paolozaffino/32/81052_2.png) [@PaoloZaffino](https://discourse.slicer.org/u/PaoloZaffino)\
**Post date:** [May 25, 2020, 7:04pm UTC](https://discourse.slicer.org/t/custom-signal-slots-with-pythonqt/3278/9 "2020-05-25T19:04:07Z")

</div>

Thanks Andras,  
I used the observe/invoke mechanism of MRML node.

Paolo
