uTools-Manuals/docs/PyQt5/事件和信号.html
2019-05-07 01:01:38 +08:00

350 lines
33 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<h1 id="事件和信号">事件和信号</h1>
<h2 id="事件">事件</h2>
<blockquote>
<p>signals and slots 被其他人翻译成信号和槽机制,(⊙o⊙)…我这里还是不翻译好了。</p>
</blockquote>
<p>所有的应用都是事件驱动的。事件大部分都是由用户的行为产生的当然也有其他的事件产生方式比如网络的连接窗口管理器或者定时器等。调用应用的exec_()方法时,应用会进入主循环,主循环会监听和分发事件。</p>
<p>在事件模型中,有三个角色:</p>
<ul>
<li>事件源</li>
<li>事件</li>
<li>事件目标</li>
</ul>
<p>事件源就是发生了状态改变的对象。事件是这个对象状态改变的内容。事件目标是事件想作用的目标。事件源绑定事件处理函数,然后作用于事件目标身上。</p>
<p>PyQt5处理事件方面有个signal and slot机制。Signals and slots用于对象间的通讯。事件触发的时候发生一个signalslot是用来被Python调用的相当于一个句柄这个词也好恶心就是相当于事件的绑定函数slot只有在事件触发的时候才能调用。</p>
<h2 id="signals-slots">Signals &amp; slots</h2>
<p>下面是signal &amp; slot的演示</p>
<div class="sourceCode" id="cb1"><pre><code class="language-python"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb1-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb1-3" data-line-number="3"></a>
<a class="sourceLine" id="cb1-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb1-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb1-6" data-line-number="6"></a>
<a class="sourceLine" id="cb1-7" data-line-number="7"><span class="co">In this example, we connect a signal</span></a>
<a class="sourceLine" id="cb1-8" data-line-number="8"><span class="co">of a QSlider to a slot of a QLCDNumber. </span></a>
<a class="sourceLine" id="cb1-9" data-line-number="9"></a>
<a class="sourceLine" id="cb1-10" data-line-number="10"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb1-11" data-line-number="11"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb1-12" data-line-number="12"><span class="co">Last edited: January 2017</span></a>
<a class="sourceLine" id="cb1-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb1-14" data-line-number="14"></a>
<a class="sourceLine" id="cb1-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb1-16" data-line-number="16"><span class="im">from</span> PyQt5.QtCore <span class="im">import</span> Qt</a>
<a class="sourceLine" id="cb1-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> (QWidget, QLCDNumber, QSlider, </a>
<a class="sourceLine" id="cb1-18" data-line-number="18"> QVBoxLayout, QApplication)</a>
<a class="sourceLine" id="cb1-19" data-line-number="19"></a>
<a class="sourceLine" id="cb1-20" data-line-number="20"></a>
<a class="sourceLine" id="cb1-21" data-line-number="21"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb1-22" data-line-number="22"> </a>
<a class="sourceLine" id="cb1-23" data-line-number="23"> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb1-24" data-line-number="24"> <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb1-25" data-line-number="25"> </a>
<a class="sourceLine" id="cb1-26" data-line-number="26"> <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb1-27" data-line-number="27"> </a>
<a class="sourceLine" id="cb1-28" data-line-number="28"> </a>
<a class="sourceLine" id="cb1-29" data-line-number="29"> <span class="kw">def</span> initUI(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb1-30" data-line-number="30"> </a>
<a class="sourceLine" id="cb1-31" data-line-number="31"> lcd <span class="op">=</span> QLCDNumber(<span class="va">self</span>)</a>
<a class="sourceLine" id="cb1-32" data-line-number="32"> sld <span class="op">=</span> QSlider(Qt.Horizontal, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb1-33" data-line-number="33"></a>
<a class="sourceLine" id="cb1-34" data-line-number="34"> vbox <span class="op">=</span> QVBoxLayout()</a>
<a class="sourceLine" id="cb1-35" data-line-number="35"> vbox.addWidget(lcd)</a>
<a class="sourceLine" id="cb1-36" data-line-number="36"> vbox.addWidget(sld)</a>
<a class="sourceLine" id="cb1-37" data-line-number="37"></a>
<a class="sourceLine" id="cb1-38" data-line-number="38"> <span class="va">self</span>.setLayout(vbox)</a>
<a class="sourceLine" id="cb1-39" data-line-number="39"> sld.valueChanged.<span class="ex">connect</span>(lcd.display)</a>
<a class="sourceLine" id="cb1-40" data-line-number="40"> </a>
<a class="sourceLine" id="cb1-41" data-line-number="41"> <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">250</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb1-42" data-line-number="42"> <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Signal and slot&#39;</span>)</a>
<a class="sourceLine" id="cb1-43" data-line-number="43"> <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb1-44" data-line-number="44"> </a>
<a class="sourceLine" id="cb1-45" data-line-number="45"></a>
<a class="sourceLine" id="cb1-46" data-line-number="46"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb1-47" data-line-number="47"> </a>
<a class="sourceLine" id="cb1-48" data-line-number="48"> app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb1-49" data-line-number="49"> ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb1-50" data-line-number="50"> sys.exit(app.exec_())</a></code></pre></div>
<p>上面的例子中,显示了<code>QtGui.QLCDNumber</code><code>QtGui.QSlider</code>模块,我们能拖动滑块让数字跟着发生改变。</p>
<pre><code class="language-python">sld.valueChanged.connect(lcd.display)</code></pre>
<p>这里是把滑块的变化和数字的变化绑定在一起。</p>
<p><code>sender</code>是信号的发送者,<code>receiver</code>是信号的接收者,<code>slot</code>是对这个信号应该做出的反应。</p>
<p>程序展示:</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/4-sigslot.png" alt="signal &amp; slot" />
</figure>
<h2 id="重构事件处理器">重构事件处理器</h2>
<p>在PyQt5中事件处理器经常被重写也就是用自己的覆盖库自带的</p>
<div class="sourceCode" id="cb3"><pre><code class="language-python"><a class="sourceLine" id="cb3-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb3-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb3-3" data-line-number="3"></a>
<a class="sourceLine" id="cb3-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb3-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb3-6" data-line-number="6"></a>
<a class="sourceLine" id="cb3-7" data-line-number="7"><span class="co">In this example, we reimplement an </span></a>
<a class="sourceLine" id="cb3-8" data-line-number="8"><span class="co">event handler. </span></a>
<a class="sourceLine" id="cb3-9" data-line-number="9"></a>
<a class="sourceLine" id="cb3-10" data-line-number="10"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb3-11" data-line-number="11"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb3-12" data-line-number="12"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb3-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb3-14" data-line-number="14"></a>
<a class="sourceLine" id="cb3-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb3-16" data-line-number="16"><span class="im">from</span> PyQt5.QtCore <span class="im">import</span> Qt</a>
<a class="sourceLine" id="cb3-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QWidget, QApplication</a>
<a class="sourceLine" id="cb3-18" data-line-number="18"></a>
<a class="sourceLine" id="cb3-19" data-line-number="19"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb3-20" data-line-number="20"> </a>
<a class="sourceLine" id="cb3-21" data-line-number="21"> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb3-22" data-line-number="22"> <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb3-23" data-line-number="23"> </a>
<a class="sourceLine" id="cb3-24" data-line-number="24"> <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb3-25" data-line-number="25"> </a>
<a class="sourceLine" id="cb3-26" data-line-number="26"> </a>
<a class="sourceLine" id="cb3-27" data-line-number="27"> <span class="kw">def</span> initUI(<span class="va">self</span>): </a>
<a class="sourceLine" id="cb3-28" data-line-number="28"> </a>
<a class="sourceLine" id="cb3-29" data-line-number="29"> <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">250</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb3-30" data-line-number="30"> <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Event handler&#39;</span>)</a>
<a class="sourceLine" id="cb3-31" data-line-number="31"> <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb3-32" data-line-number="32"> </a>
<a class="sourceLine" id="cb3-33" data-line-number="33"> </a>
<a class="sourceLine" id="cb3-34" data-line-number="34"> <span class="kw">def</span> keyPressEvent(<span class="va">self</span>, e):</a>
<a class="sourceLine" id="cb3-35" data-line-number="35"> </a>
<a class="sourceLine" id="cb3-36" data-line-number="36"> <span class="cf">if</span> e.key() <span class="op">==</span> Qt.Key_Escape:</a>
<a class="sourceLine" id="cb3-37" data-line-number="37"> <span class="va">self</span>.close()</a>
<a class="sourceLine" id="cb3-38" data-line-number="38"> </a>
<a class="sourceLine" id="cb3-39" data-line-number="39"> </a>
<a class="sourceLine" id="cb3-40" data-line-number="40"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb3-41" data-line-number="41"> </a>
<a class="sourceLine" id="cb3-42" data-line-number="42"> app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb3-43" data-line-number="43"> ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb3-44" data-line-number="44"> sys.exit(app.exec_())</a></code></pre></div>
<p>这个例子中,我们替换了事件处理器函数<code>keyPressEvent()</code></p>
<pre><code class="language-python">def keyPressEvent(self, e):
if e.key() == Qt.Key_Escape:
self.close()</code></pre>
<p>此时如果按下ESC键程序就会退出。</p>
<p>程序展示:</p>
<p>这个就一个框,啥也没,就不展示了。</p>
<h2 id="事件对象">事件对象</h2>
<p>事件对象是用python来描述一系列的事件自身属性的对象。</p>
<div class="sourceCode" id="cb5"><pre><code class="language-python"><a class="sourceLine" id="cb5-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb5-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb5-3" data-line-number="3"></a>
<a class="sourceLine" id="cb5-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb5-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb5-6" data-line-number="6"></a>
<a class="sourceLine" id="cb5-7" data-line-number="7"><span class="co">In this example, we display the x and y </span></a>
<a class="sourceLine" id="cb5-8" data-line-number="8"><span class="co">coordinates of a mouse pointer in a label widget.</span></a>
<a class="sourceLine" id="cb5-9" data-line-number="9"></a>
<a class="sourceLine" id="cb5-10" data-line-number="10"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb5-11" data-line-number="11"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb5-12" data-line-number="12"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb5-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb5-14" data-line-number="14"></a>
<a class="sourceLine" id="cb5-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb5-16" data-line-number="16"><span class="im">from</span> PyQt5.QtCore <span class="im">import</span> Qt</a>
<a class="sourceLine" id="cb5-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QWidget, QApplication, QGridLayout, QLabel</a>
<a class="sourceLine" id="cb5-18" data-line-number="18"></a>
<a class="sourceLine" id="cb5-19" data-line-number="19"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb5-20" data-line-number="20"> </a>
<a class="sourceLine" id="cb5-21" data-line-number="21"> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb5-22" data-line-number="22"> <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb5-23" data-line-number="23"> </a>
<a class="sourceLine" id="cb5-24" data-line-number="24"> <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb5-25" data-line-number="25"> </a>
<a class="sourceLine" id="cb5-26" data-line-number="26"> </a>
<a class="sourceLine" id="cb5-27" data-line-number="27"> <span class="kw">def</span> initUI(<span class="va">self</span>): </a>
<a class="sourceLine" id="cb5-28" data-line-number="28"> </a>
<a class="sourceLine" id="cb5-29" data-line-number="29"> grid <span class="op">=</span> QGridLayout()</a>
<a class="sourceLine" id="cb5-30" data-line-number="30"> grid.setSpacing(<span class="dv">10</span>)</a>
<a class="sourceLine" id="cb5-31" data-line-number="31"> </a>
<a class="sourceLine" id="cb5-32" data-line-number="32"> x <span class="op">=</span> <span class="dv">0</span></a>
<a class="sourceLine" id="cb5-33" data-line-number="33"> y <span class="op">=</span> <span class="dv">0</span></a>
<a class="sourceLine" id="cb5-34" data-line-number="34"> </a>
<a class="sourceLine" id="cb5-35" data-line-number="35"> <span class="va">self</span>.text <span class="op">=</span> <span class="st">&quot;x: </span><span class="sc">{0}</span><span class="st">, y: </span><span class="sc">{1}</span><span class="st">&quot;</span>.<span class="bu">format</span>(x, y)</a>
<a class="sourceLine" id="cb5-36" data-line-number="36"> </a>
<a class="sourceLine" id="cb5-37" data-line-number="37"> <span class="va">self</span>.label <span class="op">=</span> QLabel(<span class="va">self</span>.text, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb5-38" data-line-number="38"> grid.addWidget(<span class="va">self</span>.label, <span class="dv">0</span>, <span class="dv">0</span>, Qt.AlignTop)</a>
<a class="sourceLine" id="cb5-39" data-line-number="39"> </a>
<a class="sourceLine" id="cb5-40" data-line-number="40"> <span class="va">self</span>.setMouseTracking(<span class="va">True</span>)</a>
<a class="sourceLine" id="cb5-41" data-line-number="41"> </a>
<a class="sourceLine" id="cb5-42" data-line-number="42"> <span class="va">self</span>.setLayout(grid)</a>
<a class="sourceLine" id="cb5-43" data-line-number="43"> </a>
<a class="sourceLine" id="cb5-44" data-line-number="44"> <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">350</span>, <span class="dv">200</span>)</a>
<a class="sourceLine" id="cb5-45" data-line-number="45"> <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Event object&#39;</span>)</a>
<a class="sourceLine" id="cb5-46" data-line-number="46"> <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb5-47" data-line-number="47"> </a>
<a class="sourceLine" id="cb5-48" data-line-number="48"> </a>
<a class="sourceLine" id="cb5-49" data-line-number="49"> <span class="kw">def</span> mouseMoveEvent(<span class="va">self</span>, e):</a>
<a class="sourceLine" id="cb5-50" data-line-number="50"> </a>
<a class="sourceLine" id="cb5-51" data-line-number="51"> x <span class="op">=</span> e.x()</a>
<a class="sourceLine" id="cb5-52" data-line-number="52"> y <span class="op">=</span> e.y()</a>
<a class="sourceLine" id="cb5-53" data-line-number="53"> </a>
<a class="sourceLine" id="cb5-54" data-line-number="54"> text <span class="op">=</span> <span class="st">&quot;x: </span><span class="sc">{0}</span><span class="st">, y: </span><span class="sc">{1}</span><span class="st">&quot;</span>.<span class="bu">format</span>(x, y)</a>
<a class="sourceLine" id="cb5-55" data-line-number="55"> <span class="va">self</span>.label.setText(text)</a>
<a class="sourceLine" id="cb5-56" data-line-number="56"> </a>
<a class="sourceLine" id="cb5-57" data-line-number="57"> </a>
<a class="sourceLine" id="cb5-58" data-line-number="58"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb5-59" data-line-number="59"> </a>
<a class="sourceLine" id="cb5-60" data-line-number="60"> app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb5-61" data-line-number="61"> ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb5-62" data-line-number="62"> sys.exit(app.exec_())</a></code></pre></div>
<p>这个示例中我们在一个组件里显示鼠标的X和Y坐标。</p>
<pre><code class="language-python">self.text = &quot;x: {0}, y: {1}&quot;.format(x, y)
self.label = QLabel(self.text, self)</code></pre>
<p>X Y坐标显示在<code>QLabel</code>组件里</p>
<pre><code class="language-python">self.setMouseTracking(True)</code></pre>
<p>事件追踪默认没有开启,当开启后才会追踪鼠标的点击事件。</p>
<pre><code class="language-python">def mouseMoveEvent(self, e):
x = e.x()
y = e.y()
text = &quot;x: {0}, y: {1}&quot;.format(x, y)
self.label.setText(text)</code></pre>
<p><code>e</code>代表了事件对象。里面有我们触发事件(鼠标移动)的事件对象。<code>x()</code><code>y()</code>方法得到鼠标的x和y坐标点然后拼成字符串输出到<code>QLabel</code>组件里。</p>
<p>程序展示:</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/4-eventobject.png" alt="event object" />
</figure>
<h2 id="事件发送">事件发送</h2>
<p>有时候我们会想知道是哪个组件发出了一个信号PyQt5里的<code>sender()</code>方法能搞定这件事。</p>
<div class="sourceCode" id="cb9"><pre><code class="language-python"><a class="sourceLine" id="cb9-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb9-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb9-3" data-line-number="3"></a>
<a class="sourceLine" id="cb9-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb9-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb9-6" data-line-number="6"></a>
<a class="sourceLine" id="cb9-7" data-line-number="7"><span class="co">In this example, we determine the event sender</span></a>
<a class="sourceLine" id="cb9-8" data-line-number="8"><span class="co">object.</span></a>
<a class="sourceLine" id="cb9-9" data-line-number="9"></a>
<a class="sourceLine" id="cb9-10" data-line-number="10"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb9-11" data-line-number="11"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb9-12" data-line-number="12"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb9-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb9-14" data-line-number="14"></a>
<a class="sourceLine" id="cb9-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb9-16" data-line-number="16"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QMainWindow, QPushButton, QApplication</a>
<a class="sourceLine" id="cb9-17" data-line-number="17"></a>
<a class="sourceLine" id="cb9-18" data-line-number="18"></a>
<a class="sourceLine" id="cb9-19" data-line-number="19"><span class="kw">class</span> Example(QMainWindow):</a>
<a class="sourceLine" id="cb9-20" data-line-number="20"> </a>
<a class="sourceLine" id="cb9-21" data-line-number="21"> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb9-22" data-line-number="22"> <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb9-23" data-line-number="23"> </a>
<a class="sourceLine" id="cb9-24" data-line-number="24"> <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb9-25" data-line-number="25"> </a>
<a class="sourceLine" id="cb9-26" data-line-number="26"> </a>
<a class="sourceLine" id="cb9-27" data-line-number="27"> <span class="kw">def</span> initUI(<span class="va">self</span>): </a>
<a class="sourceLine" id="cb9-28" data-line-number="28"></a>
<a class="sourceLine" id="cb9-29" data-line-number="29"> btn1 <span class="op">=</span> QPushButton(<span class="st">&quot;Button 1&quot;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb9-30" data-line-number="30"> btn1.move(<span class="dv">30</span>, <span class="dv">50</span>)</a>
<a class="sourceLine" id="cb9-31" data-line-number="31"></a>
<a class="sourceLine" id="cb9-32" data-line-number="32"> btn2 <span class="op">=</span> QPushButton(<span class="st">&quot;Button 2&quot;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb9-33" data-line-number="33"> btn2.move(<span class="dv">150</span>, <span class="dv">50</span>)</a>
<a class="sourceLine" id="cb9-34" data-line-number="34"> </a>
<a class="sourceLine" id="cb9-35" data-line-number="35"> btn1.clicked.<span class="ex">connect</span>(<span class="va">self</span>.buttonClicked) </a>
<a class="sourceLine" id="cb9-36" data-line-number="36"> btn2.clicked.<span class="ex">connect</span>(<span class="va">self</span>.buttonClicked)</a>
<a class="sourceLine" id="cb9-37" data-line-number="37"> </a>
<a class="sourceLine" id="cb9-38" data-line-number="38"> <span class="va">self</span>.statusBar()</a>
<a class="sourceLine" id="cb9-39" data-line-number="39"> </a>
<a class="sourceLine" id="cb9-40" data-line-number="40"> <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">290</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb9-41" data-line-number="41"> <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Event sender&#39;</span>)</a>
<a class="sourceLine" id="cb9-42" data-line-number="42"> <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb9-43" data-line-number="43"> </a>
<a class="sourceLine" id="cb9-44" data-line-number="44"> </a>
<a class="sourceLine" id="cb9-45" data-line-number="45"> <span class="kw">def</span> buttonClicked(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb9-46" data-line-number="46"> </a>
<a class="sourceLine" id="cb9-47" data-line-number="47"> sender <span class="op">=</span> <span class="va">self</span>.sender()</a>
<a class="sourceLine" id="cb9-48" data-line-number="48"> <span class="va">self</span>.statusBar().showMessage(sender.text() <span class="op">+</span> <span class="st">&#39; was pressed&#39;</span>)</a>
<a class="sourceLine" id="cb9-49" data-line-number="49"> </a>
<a class="sourceLine" id="cb9-50" data-line-number="50"> </a>
<a class="sourceLine" id="cb9-51" data-line-number="51"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb9-52" data-line-number="52"> </a>
<a class="sourceLine" id="cb9-53" data-line-number="53"> app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb9-54" data-line-number="54"> ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb9-55" data-line-number="55"> sys.exit(app.exec_())</a></code></pre></div>
<p>这个例子里有俩按钮,<code>buttonClicked()</code>方法决定了是哪个按钮能调用<code>sender()</code>方法。</p>
<pre><code class="language-python">btn1.clicked.connect(self.buttonClicked)
btn2.clicked.connect(self.buttonClicked)</code></pre>
<p>两个按钮都和同一个slot绑定。</p>
<pre><code class="language-python">def buttonClicked(self):
sender = self.sender()
self.statusBar().showMessage(sender.text() + &#39; was pressed&#39;)</code></pre>
<p>我们用调用<code>sender()</code>方法的方式决定了事件源。状态栏显示了被点击的按钮。</p>
<p>程序展示:</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/4-eventsender.png" alt="event sender" />
</figure>
<h2 id="信号发送">信号发送</h2>
<p><code>QObject</code>实例能发送事件信号。下面的例子是发送自定义的信号。</p>
<div class="sourceCode" id="cb12"><pre><code class="language-python"><a class="sourceLine" id="cb12-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb12-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb12-3" data-line-number="3"></a>
<a class="sourceLine" id="cb12-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb12-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb12-6" data-line-number="6"></a>
<a class="sourceLine" id="cb12-7" data-line-number="7"><span class="co">In this example, we show how to </span></a>
<a class="sourceLine" id="cb12-8" data-line-number="8"><span class="co">emit a custom signal. </span></a>
<a class="sourceLine" id="cb12-9" data-line-number="9"></a>
<a class="sourceLine" id="cb12-10" data-line-number="10"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb12-11" data-line-number="11"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb12-12" data-line-number="12"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb12-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb12-14" data-line-number="14"></a>
<a class="sourceLine" id="cb12-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb12-16" data-line-number="16"><span class="im">from</span> PyQt5.QtCore <span class="im">import</span> pyqtSignal, QObject</a>
<a class="sourceLine" id="cb12-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QMainWindow, QApplication</a>
<a class="sourceLine" id="cb12-18" data-line-number="18"></a>
<a class="sourceLine" id="cb12-19" data-line-number="19"></a>
<a class="sourceLine" id="cb12-20" data-line-number="20"><span class="kw">class</span> Communicate(QObject):</a>
<a class="sourceLine" id="cb12-21" data-line-number="21"> </a>
<a class="sourceLine" id="cb12-22" data-line-number="22"> closeApp <span class="op">=</span> pyqtSignal() </a>
<a class="sourceLine" id="cb12-23" data-line-number="23"> </a>
<a class="sourceLine" id="cb12-24" data-line-number="24"></a>
<a class="sourceLine" id="cb12-25" data-line-number="25"><span class="kw">class</span> Example(QMainWindow):</a>
<a class="sourceLine" id="cb12-26" data-line-number="26"> </a>
<a class="sourceLine" id="cb12-27" data-line-number="27"> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb12-28" data-line-number="28"> <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb12-29" data-line-number="29"> </a>
<a class="sourceLine" id="cb12-30" data-line-number="30"> <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb12-31" data-line-number="31"> </a>
<a class="sourceLine" id="cb12-32" data-line-number="32"> </a>
<a class="sourceLine" id="cb12-33" data-line-number="33"> <span class="kw">def</span> initUI(<span class="va">self</span>): </a>
<a class="sourceLine" id="cb12-34" data-line-number="34"></a>
<a class="sourceLine" id="cb12-35" data-line-number="35"> <span class="va">self</span>.c <span class="op">=</span> Communicate()</a>
<a class="sourceLine" id="cb12-36" data-line-number="36"> <span class="va">self</span>.c.closeApp.<span class="ex">connect</span>(<span class="va">self</span>.close) </a>
<a class="sourceLine" id="cb12-37" data-line-number="37"> </a>
<a class="sourceLine" id="cb12-38" data-line-number="38"> <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">290</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb12-39" data-line-number="39"> <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Emit signal&#39;</span>)</a>
<a class="sourceLine" id="cb12-40" data-line-number="40"> <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb12-41" data-line-number="41"> </a>
<a class="sourceLine" id="cb12-42" data-line-number="42"> </a>
<a class="sourceLine" id="cb12-43" data-line-number="43"> <span class="kw">def</span> mousePressEvent(<span class="va">self</span>, event):</a>
<a class="sourceLine" id="cb12-44" data-line-number="44"> </a>
<a class="sourceLine" id="cb12-45" data-line-number="45"> <span class="va">self</span>.c.closeApp.emit()</a>
<a class="sourceLine" id="cb12-46" data-line-number="46"> </a>
<a class="sourceLine" id="cb12-47" data-line-number="47"> </a>
<a class="sourceLine" id="cb12-48" data-line-number="48"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb12-49" data-line-number="49"> </a>
<a class="sourceLine" id="cb12-50" data-line-number="50"> app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb12-51" data-line-number="51"> ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb12-52" data-line-number="52"> sys.exit(app.exec_())</a></code></pre></div>
<p>我们创建了一个叫closeApp的信号这个信号会在鼠标按下的时候触发事件与<code>QMainWindow</code>绑定。</p>
<pre><code class="language-python">class Communicate(QObject):
closeApp = pyqtSignal()</code></pre>
<p><code>Communicate</code>类创建了一个<code>pyqtSignal()</code>属性的信号。</p>
<pre><code class="language-python">self.c = Communicate()
self.c.closeApp.connect(self.close) </code></pre>
<p><code>closeApp</code>信号<code>QMainWindow</code><code>close()</code>方法绑定。</p>
<pre><code class="language-python">def mousePressEvent(self, event):
self.c.closeApp.emit()</code></pre>
<p>点击窗口的时候发送closeApp信号程序终止。</p>
<p>程序展示:</p>
<p>这个也是啥也没。</p>