How to send None with Signals across threads?
Question: I've implemented a version of the worker pattern that is described in the [Qt
Threading docs](http://doc.qt.io/qt-4.8/qthread.html).

I'm using `Signals/Slots` to send data between the worker thread and the main
thread.

When defining the `Signal`, I've set the argument signature type to `object`
since I believe it should allow me to pass any python object through the
`Signal`.

    
    
    result_ready = QtCore.Signal(object)
    

However, when I try to pass `None` through the `Signal` it crashes python.
This only happens when trying to pass the `Signal` across threads. If I
comment out the `self.worker.moveToThread(self.thread)` line, it works and
`None` is successfully passed through the `Signal`.

Why am I unable to pass `None` in this instance?

I'm using `PySide 1.2.2` and `Qt 4.8.5`.

    
    
    import sys
    
    from PySide import QtCore, QtGui
    
    
    class Worker(QtCore.QObject):
    
        result_ready = QtCore.Signal(object)
    
        @QtCore.Slot()
        def work(self):
            print 'In Worker'
    
            # This works
            self.result_ready.emit('Value')
    
            # This causes python to crash
            self.result_ready.emit(None)
    
    
    class Main(QtGui.QWidget):
    
        def __init__(self):
            super(Main, self).__init__()
            self.ui_lay = QtGui.QVBoxLayout()
            self.setLayout(self.ui_lay)
            self.ui_btn = QtGui.QPushButton('Test', self)
            self.ui_lay.addWidget(self.ui_btn)
            self.ui_lay.addStretch()
            self.setGeometry(400, 400, 400, 400)
            self.worker = Worker()
            self.thread = QtCore.QThread(self)
            self.worker.moveToThread(self.thread)
            self.thread.start()
            self.ui_btn.clicked.connect(self.worker.work)
            self.worker.result_ready.connect(self.handle_worker_result)
    
        @QtCore.Slot(object)
        def handle_worker_result(self, result=None):
            print 'Handling output', result
    
        def closeEvent(self, event):
            self.thread.quit()
            self.thread.wait()
            super(Main, self).closeEvent(event)
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        obj = Main()
        obj.show()
        app.exec_()
    


Answer: This looks like a PySide bug. The same example code works exactly as expected
with PyQt4.

The issue is with the [type of signal
connection](http://doc.qt.io/qt-4.8/qt.html#ConnectionType-enum). For cross-
thread signals, this will use a `QueuedConnection` unless you specify
otherwise. If the connection type is changed to `DirectConnection` in the
example code, it will work as expected - but of course it won't be thread-safe
anymore.

A `QueuedConnection` will post an event to the event-queue of the receiving
thread. But in order for this to be thread-safe, Qt has to serialize the
emitted arguments. However, PySide will obviously need to inject some magic
here to deal with python types that Qt doesn't know anything about. If I had
to guess, I would bet that PySide is mistakenly converting the python `None`
object to a C++ NULL pointer, which will obviously have nasty consequences
later on.

If you want to work around this, I suppose you could emit your own sentinel
object as a placeholder for `None`.

**UPDATE** :

Found the bug, [PYSIDE-17](http://bugreports.qt.io/browse/PYSIDE-17), which
was posted in March 2012! Sadly, the suggested patch seems to have never been
reviewed.

