<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Eli Bendersky's website - Qt</title><link href="https://eli.thegreenplace.net/" rel="alternate"></link><link href="https://eli.thegreenplace.net/feeds/qt.atom.xml" rel="self"></link><id>https://eli.thegreenplace.net/</id><updated>2024-05-04T19:46:23-07:00</updated><entry><title>Passing extra arguments to Qt slots</title><link href="https://eli.thegreenplace.net/2011/07/09/passing-extra-arguments-to-qt-slots" rel="alternate"></link><published>2011-07-09T10:45:11-07:00</published><updated>2023-02-04T13:41:52-08:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2011-07-09:/2011/07/09/passing-extra-arguments-to-qt-slots</id><summary type="html">
        &lt;p&gt;A few months ago I wrote about &lt;a class="reference external" href="https://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot/"&gt;passing extra arguments to slots in PyQt&lt;/a&gt;. Here, I want to briefly discuss how the same effect can be achieved with Qt itself.&lt;/p&gt;
&lt;p&gt;C++ is not as dynamic as Python, so Python's approaches of using &lt;tt class="docutils literal"&gt;lambda&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;functools.partial&lt;/tt&gt; won't work &lt;a class="footnote-reference" href="#id3" id="id1"&gt;[1]&lt;/a&gt;. Fortunately …&lt;/p&gt;</summary><content type="html">
        &lt;p&gt;A few months ago I wrote about &lt;a class="reference external" href="https://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot/"&gt;passing extra arguments to slots in PyQt&lt;/a&gt;. Here, I want to briefly discuss how the same effect can be achieved with Qt itself.&lt;/p&gt;
&lt;p&gt;C++ is not as dynamic as Python, so Python's approaches of using &lt;tt class="docutils literal"&gt;lambda&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;functools.partial&lt;/tt&gt; won't work &lt;a class="footnote-reference" href="#id3" id="id1"&gt;[1]&lt;/a&gt;. Fortunately, the Qt folks provided a solution that can make passing extra arguments to slots relatively simple. This is the &lt;tt class="docutils literal"&gt;QSignalMapper&lt;/tt&gt; class.&lt;/p&gt;
&lt;p&gt;I'll just show a partial code sample. Suppose we have two different &lt;tt class="docutils literal"&gt;QAction&lt;/tt&gt; objects, and we want to connect both to the slot:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt; onAction(&lt;span style="color: #00007f; font-weight: bold"&gt;const&lt;/span&gt; QString&amp;amp; what);
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Further, we want each action to pass a different argument to &lt;tt class="docutils literal"&gt;onAction&lt;/tt&gt;. Here's the relevant connections using &lt;tt class="docutils literal"&gt;QSignalMapper&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #007f00"&gt;// #1&lt;/span&gt;
m_sigmapper = &lt;span style="color: #00007f; font-weight: bold"&gt;new&lt;/span&gt; QSignalMapper(&lt;span style="color: #00007f; font-weight: bold"&gt;this&lt;/span&gt;);

&lt;span style="color: #007f00"&gt;// #2&lt;/span&gt;
connect(m_action_file_new, SIGNAL(triggered()),
        m_sigmapper, SLOT(map()));
connect(m_action_file_open, SIGNAL(triggered()),
        m_sigmapper, SLOT(map()));

&lt;span style="color: #007f00"&gt;// #3&lt;/span&gt;
m_sigmapper-&amp;gt;setMapping(m_action_file_new, &lt;span style="color: #7f007f"&gt;&amp;quot;File-&amp;gt;New&amp;quot;&lt;/span&gt;);
m_sigmapper-&amp;gt;setMapping(m_action_file_open, &lt;span style="color: #7f007f"&gt;&amp;quot;File-&amp;gt;Open&amp;quot;&lt;/span&gt;);

&lt;span style="color: #007f00"&gt;// #4&lt;/span&gt;
connect(m_sigmapper, SIGNAL(mapped(QString)),
        &lt;span style="color: #00007f; font-weight: bold"&gt;this&lt;/span&gt;, SLOT(onAction(&lt;span style="color: #00007f; font-weight: bold"&gt;const&lt;/span&gt; QString&amp;amp;)));
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are four distinct steps here:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Create a new &lt;tt class="docutils literal"&gt;QSignalMapper&lt;/tt&gt; object.&lt;/li&gt;
&lt;li&gt;Connect the &lt;tt class="docutils literal"&gt;triggered&lt;/tt&gt; slots of the actions to the mapper's &lt;tt class="docutils literal"&gt;map&lt;/tt&gt; slot.&lt;/li&gt;
&lt;li&gt;Let the mapper know via &lt;tt class="docutils literal"&gt;setMapping&lt;/tt&gt; which action should pass which extra argument.&lt;/li&gt;
&lt;li&gt;Finally, connect the mapper's &lt;tt class="docutils literal"&gt;mapped(QString)&lt;/tt&gt; signal to &lt;tt class="docutils literal"&gt;onAction&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is it. Now, when &lt;tt class="docutils literal"&gt;m_action_file_new&lt;/tt&gt; is triggered, &lt;tt class="docutils literal"&gt;onAction&lt;/tt&gt; will be called with the argument &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;quot;File-&amp;gt;New&amp;quot;&lt;/span&gt;&lt;/tt&gt;, and so on.&lt;/p&gt;
&lt;p&gt;Internally, &lt;tt class="docutils literal"&gt;QSignalMapper&lt;/tt&gt; is quite simple. It contains a hash table mapping the sender &lt;tt class="docutils literal"&gt;QObject*&lt;/tt&gt; to the argument (filled in &lt;tt class="docutils literal"&gt;setMapping&lt;/tt&gt;). When its &lt;tt class="docutils literal"&gt;map&lt;/tt&gt; slot is invoked, it looks up the sender in the hash and fires &lt;tt class="docutils literal"&gt;mapped&lt;/tt&gt; with the appropriate argument.&lt;/p&gt;
&lt;p&gt;There are some limitations to &lt;tt class="docutils literal"&gt;QSignalMapper&lt;/tt&gt; - for example, you can't map arguments with arbitrary type &lt;a class="footnote-reference" href="#id4" id="id2"&gt;[2]&lt;/a&gt;, or map multiple arguments. The only mappings supported are:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt; setMapping(QObject *sender, &lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; id);
&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt; setMapping(QObject *sender, &lt;span style="color: #00007f; font-weight: bold"&gt;const&lt;/span&gt; QString &amp;amp;text);
&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt; setMapping(QObject *sender, QWidget *widget);
&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt; setMapping(QObject *sender, QObject *object);
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So if you need to pass some complex information to a slot, create a class derived from &lt;tt class="docutils literal"&gt;QObject&lt;/tt&gt; and use that.&lt;/p&gt;
&lt;img class="align-center" src="https://eli.thegreenplace.net/images/hline.jpg" style="width: 320px; height: 5px;" /&gt;
&lt;table class="docutils footnote" frame="void" id="id3" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Well, C++ &lt;em&gt;does&lt;/em&gt; have some high-level constructs like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;boost::bind&lt;/span&gt;&lt;/tt&gt; and the new C++0x standard support for lambdas, but I don't believe either approach is formally supported by Qt's &lt;tt class="docutils literal"&gt;connect&lt;/tt&gt; methods yet.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id4" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Though I guess Qt could have implemented this with templates.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

    </content><category term="misc"></category><category term="C &amp; C++"></category><category term="Qt"></category></entry><entry><title>DLL hell problems with Qt Creator</title><link href="https://eli.thegreenplace.net/2011/07/08/dll-hell-problems-with-qt-creator" rel="alternate"></link><published>2011-07-08T06:06:19-07:00</published><updated>2022-10-04T14:08:24-07:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2011-07-08:/2011/07/08/dll-hell-problems-with-qt-creator</id><summary type="html">
        &lt;p&gt;Yesterday I installed the latest version of the Qt SDK on my home machine (selecting only the desktop version for MinGW in the installation). Then I opened Qt Creator, selected one of the bundled example projects, built it and...&lt;/p&gt;
&lt;img class="align-center" src="https://eli.thegreenplace.net/images/2011/07/lol_horror.jpg" /&gt;
&lt;p&gt;And then I got this error:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;Starting D:\QtSDK\...\debug\mandelbrot …&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">
        &lt;p&gt;Yesterday I installed the latest version of the Qt SDK on my home machine (selecting only the desktop version for MinGW in the installation). Then I opened Qt Creator, selected one of the bundled example projects, built it and...&lt;/p&gt;
&lt;img class="align-center" src="https://eli.thegreenplace.net/images/2011/07/lol_horror.jpg" /&gt;
&lt;p&gt;And then I got this error:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;Starting D:\QtSDK\...\debug\mandelbrot.exe...
D:\QtSDK\...\debug\mandelbrot.exe exited with code -1073741511
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Well, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-1073741511&lt;/span&gt;&lt;/tt&gt; is just an obscene way of saying &lt;tt class="docutils literal"&gt;0xC0000139&lt;/tt&gt;, which on Windows means that some function wasn't found in a DLL. So this is Windows DLL hell (who would've thought...).&lt;/p&gt;
&lt;p&gt;Naturally, I first suspected that Qt Creator is the culprit here. This is because when I went to directory this executable was created in and copied the relevant DLLs into it, it worked. So I started digging around the project settings in Qt Creator, but it appeared that it set up the &lt;tt class="docutils literal"&gt;PATH&lt;/tt&gt; correctly to point to the installed Qt and MinGW runtime DLLs. Furthermore, it was properly appending to the beginning of &lt;tt class="docutils literal"&gt;PATH&lt;/tt&gt;, so other versions of Qt potentially installed elsewhere couldn't affect it. Or could they?&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="http://msdn.microsoft.com/en-us/library/ms682586%28v=vs.85%29.aspx"&gt;DLL search order&lt;/a&gt; on Windows, whichever way it is configured, always looks in the system and windows directories &lt;em&gt;before&lt;/em&gt; it looks at the dirs on &lt;tt class="docutils literal"&gt;PATH&lt;/tt&gt;. Indeed, when I went to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;c:\WINDOWS\system32&lt;/span&gt;&lt;/tt&gt;, I was surprised (and delighted) to find a few stray Qt DLLs in there. Deleting them solved the problem!&lt;/p&gt;
&lt;p&gt;The morale of the story: always think about the &amp;quot;DLL search order&amp;quot; when debugging problems like this. &lt;a class="reference external" href="http://www.dependencywalker.com/"&gt;Dependency walker&lt;/a&gt; can help greatly here too. If your executable finds a DLL somewhere you wouldn't expect it to, &lt;tt class="docutils literal"&gt;depends&lt;/tt&gt; will tell you about it.&lt;/p&gt;
&lt;p&gt;P.S. How did the debug DLLs of Qt get into my &lt;tt class="docutils literal"&gt;system32&lt;/tt&gt;? Either some application put them there during installation (a bad, bad thing to do), or I put them there for some obscure testing purpose a while ago and forgot all about them. Therefore, another morale of the story: never, &lt;em&gt;EVER&lt;/em&gt;, put stuff in &lt;tt class="docutils literal"&gt;system32&lt;/tt&gt;. Just distribute your DLLs in the same directory with the executable. Modern hard-drives are large enough to make the storage savings of DLL sharing negligible.&lt;/p&gt;

    </content><category term="misc"></category><category term="C &amp; C++"></category><category term="Qt"></category><category term="Windows"></category></entry><entry><title>Code sample - socket client based on Twisted with PyQt</title><link href="https://eli.thegreenplace.net/2011/05/26/code-sample-socket-client-based-on-twisted-with-pyqt" rel="alternate"></link><published>2011-05-26T05:28:59-07:00</published><updated>2024-05-04T19:46:23-07:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2011-05-26:/2011/05/26/code-sample-socket-client-based-on-twisted-with-pyqt</id><summary type="html">
        &lt;p&gt;In an &lt;a class="reference external" href="https://eli.thegreenplace.net/2011/05/18/code-sample-socket-client-thread-in-python/"&gt;earlier post&lt;/a&gt;, I discussed one way of combining blocking socket I/O with a GUI, by means of a separate thread in which the I/O runs. I've also mentioned that one alternative is using asynchronous I/O with callbacks integrated into the GUI event loop. Here I …&lt;/p&gt;</summary><content type="html">
        &lt;p&gt;In an &lt;a class="reference external" href="https://eli.thegreenplace.net/2011/05/18/code-sample-socket-client-thread-in-python/"&gt;earlier post&lt;/a&gt;, I discussed one way of combining blocking socket I/O with a GUI, by means of a separate thread in which the I/O runs. I've also mentioned that one alternative is using asynchronous I/O with callbacks integrated into the GUI event loop. Here I want to present some sample code for this alternative.&lt;/p&gt;
&lt;p&gt;One of the first things Python programmers will think about then considering asynchronous I/O is &lt;a class="reference external" href="http://twistedmatrix.com/trac/"&gt;Twisted&lt;/a&gt;, which is an event-driven networking library written in pure Python. Twisted is a huge library, and it's quite a job to learn how to use it properly. Here I'll demonstrate just enough to accomplish the task at hand - re-create the simple socket client from the previous post that works as part of a PyQt GUI.&lt;/p&gt;
&lt;p&gt;The full code sample is available for download - &lt;a class="reference external" href="https://github.com/eliben/code-for-blog/tree/main/2011/socket_client_twisted_pyqt"&gt;socket_client_twisted_pyqt&lt;/a&gt;. Here is the socket client class using Twisted:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #00007f"&gt;struct&lt;/span&gt;

&lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;twisted.internet.protocol&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; Protocol, ClientFactory
&lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;twisted.protocols.basic&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; IntNStringReceiver


&lt;span style="color: #00007f; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #00007f"&gt;SocketClientProtocol&lt;/span&gt;(IntNStringReceiver):
    &lt;span style="color: #7f007f"&gt;&amp;quot;&amp;quot;&amp;quot; The protocol is based on twisted.protocols.basic&lt;/span&gt;
&lt;span style="color: #7f007f"&gt;        IntNStringReceiver, with little-endian 32-bit&lt;/span&gt;
&lt;span style="color: #7f007f"&gt;        length prefix.&lt;/span&gt;
&lt;span style="color: #7f007f"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    structFormat = &lt;span style="color: #7f007f"&gt;&amp;quot;&amp;lt;L&amp;quot;&lt;/span&gt;
    prefixLength = struct.calcsize(structFormat)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;stringReceived&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, s):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.factory.got_msg(s)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;connectionMade&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.factory.clientReady(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;)


&lt;span style="color: #00007f; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #00007f"&gt;SocketClientFactory&lt;/span&gt;(ClientFactory):
    &lt;span style="color: #7f007f"&gt;&amp;quot;&amp;quot;&amp;quot; Created with callbacks for connection and receiving.&lt;/span&gt;
&lt;span style="color: #7f007f"&gt;        send_msg can be used to send messages when connected.&lt;/span&gt;
&lt;span style="color: #7f007f"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    protocol = SocketClientProtocol

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;__init__&lt;/span&gt;(
            &lt;span style="color: #00007f"&gt;self&lt;/span&gt;,
            connect_success_callback,
            connect_fail_callback,
            recv_callback):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.connect_success_callback = connect_success_callback
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.connect_fail_callback = connect_fail_callback
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.recv_callback = recv_callback
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.client = &lt;span style="color: #00007f"&gt;None&lt;/span&gt;

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;clientConnectionFailed&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, connector, reason):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.connect_fail_callback(reason)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;clientReady&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, client):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.client = client
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.connect_success_callback()

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;got_msg&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, msg):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.recv_callback(msg)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;send_msg&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, msg):
        &lt;span style="color: #00007f; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.client:
            &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.client.sendString(msg)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A couple of notes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Since I want to re-create the same length-prefixed protocol from the previous post, the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;IntNStringReceiver&lt;/span&gt;&lt;/tt&gt; protocol class from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;twisted.protocols.basic&lt;/span&gt;&lt;/tt&gt; comes in handy - it's designed especially for strings prefixed by integer length headers. In our case, the prefix is a 4-byte little-endian unsigned integer, which I specify with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;structFormat&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;prefixLength&lt;/span&gt;&lt;/tt&gt; attributes. In addition I implement a couple of callbacks of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;IProtocol&lt;/span&gt;&lt;/tt&gt; interface.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;SocketClientFactory&lt;/span&gt;&lt;/tt&gt; is a straightforward subclass of Twisted's &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ClientFactory&lt;/span&gt;&lt;/tt&gt;, implementing the callbacks we're interested in here.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is all quite simple. The bigger problem was finding how to interface Twisted with PyQt. Since Twisted and a typical GUI library are both event-loop based, to make them work together we should use &lt;a class="reference external" href="http://twistedmatrix.com/documents/current/core/howto/choosing-reactor.html"&gt;a custom reactor&lt;/a&gt;. Unfortunately, due to licensing issues, Twisted doesn't come with a reactor for PyQt pre-packaged, and it should be obtained separately. Even more unfortunately, the PyQt reactor (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;qt4reactor.py&lt;/span&gt;&lt;/tt&gt;) doesn't appear to have a single well-defined address on the web - several slightly different versions of it can be found floating online. In my code sample I've included a version of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;qt4reactor.py&lt;/span&gt;&lt;/tt&gt; which I found to work for my needs.&lt;/p&gt;
&lt;p&gt;So, back to the code. This is the implementation of the PyQt client GUI that uses Twisted. Similarly to the thread-based sample, it keeps drawing a nice circle animation to demonstrate it's never blocked. The full code is in the zip archive, here is only the interesting part:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #00007f"&gt;SampleGUIClientWindow&lt;/span&gt;(QMainWindow):
    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;__init__&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, reactor, parent=&lt;span style="color: #00007f"&gt;None&lt;/span&gt;):
        &lt;span style="color: #00007f"&gt;super&lt;/span&gt;(SampleGUIClientWindow, &lt;span style="color: #00007f"&gt;self&lt;/span&gt;).__init__(parent)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.reactor = reactor

        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.create_main_frame()
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.create_client()
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.create_timer()

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;create_main_frame&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.circle_widget = CircleWidget()
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.doit_button = QPushButton(&lt;span style="color: #7f007f"&gt;&amp;#39;Do it!&amp;#39;&lt;/span&gt;)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.doit_button.clicked.connect(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_doit)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.log_widget = LogWidget()

        hbox = QHBoxLayout()
        hbox.addWidget(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;.circle_widget)
        hbox.addWidget(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;.doit_button)
        hbox.addWidget(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;.log_widget)

        main_frame = QWidget()
        main_frame.setLayout(hbox)

        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.setCentralWidget(main_frame)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;create_timer&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.circle_timer = QTimer(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.circle_timer.timeout.connect(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;.circle_widget.next)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.circle_timer.start(&lt;span style="color: #007f7f"&gt;25&lt;/span&gt;)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;create_client&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.client = SocketClientFactory(
                        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_client_connect_success,
                        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_client_connect_fail,
                        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_client_receive)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;on_doit&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.log(&lt;span style="color: #7f007f"&gt;&amp;#39;Connecting...&amp;#39;&lt;/span&gt;)
        &lt;span style="color: #007f00"&gt;# When the connection is made, self.client calls the on_client_connect&lt;/span&gt;
        &lt;span style="color: #007f00"&gt;# callback.&lt;/span&gt;
        &lt;span style="color: #007f00"&gt;#&lt;/span&gt;
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.connection = &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.reactor.connectTCP(SERVER_HOST, SERVER_PORT, &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.client)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;on_client_connect_success&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.log(&lt;span style="color: #7f007f"&gt;&amp;#39;Connected to server. Sending...&amp;#39;&lt;/span&gt;)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.client.send_msg(&lt;span style="color: #7f007f"&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;on_client_connect_fail&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, reason):
        &lt;span style="color: #007f00"&gt;# reason is a twisted.python.failure.Failure  object&lt;/span&gt;
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.log(&lt;span style="color: #7f007f"&gt;&amp;#39;Connection failed: %s&amp;#39;&lt;/span&gt; % reason.getErrorMessage())

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;on_client_receive&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, msg):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.log(&lt;span style="color: #7f007f"&gt;&amp;#39;Client reply: %s&amp;#39;&lt;/span&gt; % msg)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.log(&lt;span style="color: #7f007f"&gt;&amp;#39;Disconnecting...&amp;#39;&lt;/span&gt;)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.connection.disconnect()

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;log&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, msg):
        timestamp = &lt;span style="color: #7f007f"&gt;&amp;#39;[%010.3f]&amp;#39;&lt;/span&gt; % time.clock()
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.log_widget.append(timestamp + &lt;span style="color: #7f007f"&gt;&amp;#39; &amp;#39;&lt;/span&gt; + &lt;span style="color: #00007f"&gt;str&lt;/span&gt;(msg))

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;closeEvent&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, e):
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.reactor.stop()


&lt;span style="color: #007f00"&gt;#-------------------------------------------------------------------------------&lt;/span&gt;
&lt;span style="color: #00007f; font-weight: bold"&gt;if&lt;/span&gt; __name__ == &lt;span style="color: #7f007f"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;:
    app = QApplication(sys.argv)

    &lt;span style="color: #00007f; font-weight: bold"&gt;try&lt;/span&gt;:
        &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #00007f"&gt;qt4reactor&lt;/span&gt;
    &lt;span style="color: #00007f; font-weight: bold"&gt;except&lt;/span&gt; ImportError:
        &lt;span style="color: #007f00"&gt;# Maybe qt4reactor is placed inside twisted.internet in site-packages?&lt;/span&gt;
        &lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;twisted.internet&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; qt4reactor
    qt4reactor.install()

    &lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;twisted.internet&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; reactor
    mainwindow = SampleGUIClientWindow(reactor)
    mainwindow.show()

    reactor.run()
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The most important part of this code is in the last section, where the Twisted reactor and PyQt application are set up. A few steps have to be performed in a careful order:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;An &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;QApplication&lt;/span&gt;&lt;/tt&gt; is created&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;qt4reactor&lt;/span&gt;&lt;/tt&gt; is imported and &lt;em&gt;installed&lt;/em&gt; into Twisted&lt;/li&gt;
&lt;li&gt;The main window is created&lt;/li&gt;
&lt;li&gt;Finally, the singleton Twisted reactor (which is actually a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;qt4reactor&lt;/span&gt;&lt;/tt&gt;, since that's the one we've installed) is run&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that there's no &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;app.exec_()&lt;/span&gt;&lt;/tt&gt; here, contrary to what you'd expect from a PyQt program. Since both PyQt and Twisted are based on event loops (in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;app.exec_()&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;reactor.run()&lt;/span&gt;&lt;/tt&gt;, respectively), one of them should drive the other. The Twisted way is to let the reactor drive (hence we only call &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;reactor.run()&lt;/span&gt;&lt;/tt&gt; here). Inside its implementation, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;qt4reactor&lt;/span&gt;&lt;/tt&gt; takes care of running an event loop in a way that dispatches events to both Twisted and PyQt.&lt;/p&gt;
&lt;p&gt;Some additional notes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The PyQt main window no longer needs a timer to query results from the client thread. When &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;SocketClientFactory&lt;/span&gt;&lt;/tt&gt; is created in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;create_client&lt;/span&gt;&lt;/tt&gt;, some methods are passed to it as callbacks. These callbacks will be invoked when interesting events happen.&lt;/li&gt;
&lt;li&gt;Even though Twisted's reactor is a global singleton object, it's good practice to pass it around in the application, instead of importing it from Twisted in multiple places. Here, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;SampleGUIClientWindow&lt;/span&gt;&lt;/tt&gt; accepts the reactor object in its constructor and uses it later.&lt;/li&gt;
&lt;li&gt;Twisted's reactor keeps running until explicitly stopped. The user of a GUI expects the program to exit then the GUI is closed, so I call &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;reactor.stop()&lt;/span&gt;&lt;/tt&gt; in the main window's &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;closeEvent&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is it. Once set up, Twisted integrates quite nicely with PyQt. Since both the GUI framework and Twisted are based on the concept of an event loop with callbacks, this is a natural symbiosis.&lt;/p&gt;
&lt;p&gt;A final note: I'm very far from being a Twisted expert. In fact, this is the first time I &lt;em&gt;really&lt;/em&gt; use it, so may be doing things not in the most idiomatic or optimal way. If you can recommend a better way to implement some parts of this sample, I'll be very happy to hear about it.&lt;/p&gt;

    </content><category term="misc"></category><category term="Python"></category><category term="Qt"></category></entry><entry><title>Passing extra arguments to PyQt slots</title><link href="https://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot" rel="alternate"></link><published>2011-04-25T13:38:41-07:00</published><updated>2022-10-04T14:08:24-07:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2011-04-25:/2011/04/25/passing-extra-arguments-to-pyqt-slot</id><summary type="html">
        &lt;p&gt;A frequent question coming up when programming with PyQt is how to pass extra arguments to slots. After all, the signal-slot connection mechanism only specifies how to connect a signal to a slot - the signal's arguments are passed to the slot, but no additional (user-defined) arguments may be directly passed …&lt;/p&gt;</summary><content type="html">
        &lt;p&gt;A frequent question coming up when programming with PyQt is how to pass extra arguments to slots. After all, the signal-slot connection mechanism only specifies how to connect a signal to a slot - the signal's arguments are passed to the slot, but no additional (user-defined) arguments may be directly passed.&lt;/p&gt;
&lt;p&gt;But passing extra arguments can be quite useful. You can have a single slot handling signals from multiple widgets, and sometimes you need to pass extra information.&lt;/p&gt;
&lt;p&gt;One way to do this is using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;lambda&lt;/span&gt;&lt;/tt&gt;. Here's a complete code sample:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;PyQt4.QtCore&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; *
&lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;PyQt4.QtGui&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; *

&lt;span style="color: #00007f; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #00007f"&gt;MyForm&lt;/span&gt;(QMainWindow):
    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;__init__&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, parent=&lt;span style="color: #00007f"&gt;None&lt;/span&gt;):
        &lt;span style="color: #00007f"&gt;super&lt;/span&gt;(MyForm, &lt;span style="color: #00007f"&gt;self&lt;/span&gt;).__init__(parent)
        button1 = QPushButton(&lt;span style="color: #7f007f"&gt;&amp;#39;Button 1&amp;#39;&lt;/span&gt;)
        button2 = QPushButton(&lt;span style="color: #7f007f"&gt;&amp;#39;Button 1&amp;#39;&lt;/span&gt;)
        button1.clicked.connect(&lt;span style="color: #00007f; font-weight: bold"&gt;lambda&lt;/span&gt;: &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_button(&lt;span style="color: #007f7f"&gt;1&lt;/span&gt;))
        button2.clicked.connect(&lt;span style="color: #00007f; font-weight: bold"&gt;lambda&lt;/span&gt;: &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_button(&lt;span style="color: #007f7f"&gt;2&lt;/span&gt;))

        layout = QHBoxLayout()
        layout.addWidget(button1)
        layout.addWidget(button2)

        main_frame = QWidget()
        main_frame.setLayout(layout)

        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.setCentralWidget(main_frame)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;on_button&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, n):
        &lt;span style="color: #00007f; font-weight: bold"&gt;print&lt;/span&gt;(&lt;span style="color: #7f007f"&gt;&amp;#39;Button {0} clicked&amp;#39;&lt;/span&gt;.format(n))

&lt;span style="color: #00007f; font-weight: bold"&gt;if&lt;/span&gt; __name__ == &lt;span style="color: #7f007f"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;:
    &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #00007f"&gt;sys&lt;/span&gt;
    app = QApplication(sys.argv)
    form = MyForm()
    form.show()
    app.exec_()
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note how the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;on_button&lt;/span&gt;&lt;/tt&gt; slot is used to handle signals from both buttons. Here we use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;lambda&lt;/span&gt;&lt;/tt&gt; to pass the button number to the slot, but anything can be passed - even the button widget itself (suppose the slot wants to deactivate the button that sent the signal).&lt;/p&gt;
&lt;p&gt;There's an alternative to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;lambda&lt;/span&gt;&lt;/tt&gt; - using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;functools.partial&lt;/span&gt;&lt;/tt&gt;. We can replace the connection lines with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;button1.clicked.connect(partial(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_button, &lt;span style="color: #007f7f"&gt;1&lt;/span&gt;))
button2.clicked.connect(partial(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_button, &lt;span style="color: #007f7f"&gt;2&lt;/span&gt;))
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Which method is better? It's really a matter of style. Personally, I prefer the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;lambda&lt;/span&gt;&lt;/tt&gt; because it's more explicit and flexible.&lt;/p&gt;

    </content><category term="misc"></category><category term="Python"></category><category term="Qt"></category></entry><entry><title>New-style signal-slot connection mechanism in PyQt</title><link href="https://eli.thegreenplace.net/2011/04/24/new-style-signal-slot-connection-mechanism-in-pyqt" rel="alternate"></link><published>2011-04-24T18:49:42-07:00</published><updated>2022-10-04T14:08:24-07:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2011-04-24:/2011/04/24/new-style-signal-slot-connection-mechanism-in-pyqt</id><summary type="html">
        &lt;p&gt;In most of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;PyQt&lt;/span&gt;&lt;/tt&gt; code samples you find online and in books (including, I confess, my examples and blog posts) the &amp;quot;old-style&amp;quot; signal-slot connection mechanism is used. For example, here's a basic push-button window:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;PyQt4.QtCore&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; *
&lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;PyQt4.QtGui&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; *

&lt;span style="color: #00007f; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #00007f"&gt;MyForm&lt;/span&gt;(QMainWindow):
    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;__init__&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, parent …&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">
        &lt;p&gt;In most of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;PyQt&lt;/span&gt;&lt;/tt&gt; code samples you find online and in books (including, I confess, my examples and blog posts) the &amp;quot;old-style&amp;quot; signal-slot connection mechanism is used. For example, here's a basic push-button window:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;PyQt4.QtCore&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; *
&lt;span style="color: #00007f; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #00007f"&gt;PyQt4.QtGui&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; *

&lt;span style="color: #00007f; font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #00007f"&gt;MyForm&lt;/span&gt;(QMainWindow):
    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;__init__&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;, parent=&lt;span style="color: #00007f"&gt;None&lt;/span&gt;):
        &lt;span style="color: #00007f"&gt;super&lt;/span&gt;(MyForm, &lt;span style="color: #00007f"&gt;self&lt;/span&gt;).__init__(parent)
        the_button = QPushButton(&lt;span style="color: #7f007f"&gt;&amp;#39;Hello&amp;#39;&lt;/span&gt;)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.connect(the_button, SIGNAL(&lt;span style="color: #7f007f"&gt;&amp;#39;clicked()&amp;#39;&lt;/span&gt;), &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_hello)
        &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.setCentralWidget(the_button)

    &lt;span style="color: #00007f; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #00007f"&gt;on_hello&lt;/span&gt;(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;):
        &lt;span style="color: #00007f; font-weight: bold"&gt;print&lt;/span&gt;(&lt;span style="color: #7f007f"&gt;&amp;#39;hello!!&amp;#39;&lt;/span&gt;)

&lt;span style="color: #00007f; font-weight: bold"&gt;if&lt;/span&gt; __name__ == &lt;span style="color: #7f007f"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;:
    &lt;span style="color: #00007f; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #00007f"&gt;sys&lt;/span&gt;
    app = QApplication(sys.argv)
    form = MyForm()
    form.show()
    app.exec_()
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The relevant code is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #00007f"&gt;self&lt;/span&gt;.connect(the_button, SIGNAL(&lt;span style="color: #7f007f"&gt;&amp;#39;clicked()&amp;#39;&lt;/span&gt;), &lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_hello)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Apart from being verbose and un-Pythonic, this syntax has a serious problem. You must type in the C++ signature of the signal exactly. Otherwise, the signal just won't fire, without an exception or any warning. This is a &lt;em&gt;very common&lt;/em&gt; mistake. If you think that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;clicked()&lt;/span&gt;&lt;/tt&gt; is a simple enough signature to write, how about these ones (taken from real code):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;SIGNAL(&lt;span style="color: #7f007f"&gt;&amp;quot;currentRowChanged(QModelIndex,QModelIndex)&amp;quot;&lt;/span&gt;)
SIGNAL(&lt;span style="color: #7f007f"&gt;&amp;#39;marginClicked(int, int, Qt::KeyboardModifiers)&amp;#39;&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &amp;quot;new-style&amp;quot; signal-slot connection mechanism is much better. Here's how the button click connection is done:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;the_button.clicked.connect(&lt;span style="color: #00007f"&gt;self&lt;/span&gt;.on_hello)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This mechanism is supported by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;PyQt&lt;/span&gt;&lt;/tt&gt; since version 4.5, and provides a safer and much more convenient way to connect signals and slots. Each signal is now an attribute that gets automatically bound once you access it. It has a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;connect&lt;/span&gt;&lt;/tt&gt; method that simply accepts the slot as a Python callable. No more C++ signatures, yay!&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;PyQt&lt;/span&gt;&lt;/tt&gt; 4.5 was released almost 2 years ago - it's time to switch to the new mechanism.&lt;/p&gt;

    </content><category term="misc"></category><category term="Python"></category><category term="Qt"></category></entry></feed>