mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-10 16:48:17 +08:00
350 lines
33 KiB
HTML
350 lines
33 KiB
HTML
<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用于对象间的通讯。事件触发的时候,发生一个signal,slot是用来被Python调用的(相当于一个句柄?这个词也好恶心,就是相当于事件的绑定函数)slot只有在事件触发的时候才能调用。</p>
|
||
<h2 id="signals-slots">Signals & slots</h2>
|
||
<p>下面是signal & 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">"""</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">"""</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">'Signal and slot'</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">'__main__'</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 & 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">"""</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">"""</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">'Event handler'</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">'__main__'</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">"""</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">"""</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">"x: </span><span class="sc">{0}</span><span class="st">, y: </span><span class="sc">{1}</span><span class="st">"</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">'Event object'</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">"x: </span><span class="sc">{0}</span><span class="st">, y: </span><span class="sc">{1}</span><span class="st">"</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">'__main__'</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 = "x: {0}, y: {1}".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 = "x: {0}, y: {1}".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">"""</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">"""</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">"Button 1"</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">"Button 2"</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">'Event sender'</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">' was pressed'</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">'__main__'</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() + ' was pressed')</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">"""</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">"""</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">'Emit signal'</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">'__main__'</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>
|