uTools-Manuals/docs/PyQt5/布局管理.html
2019-05-14 02:17:51 +08:00

297 lines
28 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>
<p>在一个GUI程序里布局是一个很重要的方面。布局就是如何管理应用中的元素和窗口。有两种方式可以搞定绝对定位和PyQt5的layout类</p>
<h2 id="绝对定位">绝对定位</h2>
<p>每个程序都是以像素为单位区分元素的位置,衡量元素的大小。所以我们完全可以使用绝对定位搞定每个元素和窗口的位置。但是这也有局限性:</p>
<ul>
<li>元素不会随着我们更改窗口的位置和大小而变化。</li>
<li>不能适用于不同的平台和不同分辨率的显示器</li>
<li>更改应用字体大小会破坏布局</li>
<li>如果我们决定重构这个应用,需要全部计算一下每个元素的位置和大小</li>
</ul>
<p>下面这个就是绝对定位的应用</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">This example shows three labels on a window</span></a>
<a class="sourceLine" id="cb1-8" data-line-number="8"><span class="co">using absolute positioning. </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: August 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.QtWidgets <span class="im">import</span> QWidget, QLabel, QApplication</a>
<a class="sourceLine" id="cb1-17" data-line-number="17"></a>
<a class="sourceLine" id="cb1-18" data-line-number="18"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb1-19" data-line-number="19"></a>
<a class="sourceLine" id="cb1-20" data-line-number="20"> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb1-21" data-line-number="21"> <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb1-22" data-line-number="22"></a>
<a class="sourceLine" id="cb1-23" data-line-number="23"> <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb1-24" data-line-number="24"></a>
<a class="sourceLine" id="cb1-25" data-line-number="25"></a>
<a class="sourceLine" id="cb1-26" data-line-number="26"> <span class="kw">def</span> initUI(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb1-27" data-line-number="27"></a>
<a class="sourceLine" id="cb1-28" data-line-number="28"> lbl1 <span class="op">=</span> QLabel(<span class="st">&#39;Zetcode&#39;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb1-29" data-line-number="29"> lbl1.move(<span class="dv">15</span>, <span class="dv">10</span>)</a>
<a class="sourceLine" id="cb1-30" data-line-number="30"></a>
<a class="sourceLine" id="cb1-31" data-line-number="31"> lbl2 <span class="op">=</span> QLabel(<span class="st">&#39;tutorials&#39;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb1-32" data-line-number="32"> lbl2.move(<span class="dv">35</span>, <span class="dv">40</span>)</a>
<a class="sourceLine" id="cb1-33" data-line-number="33"></a>
<a class="sourceLine" id="cb1-34" data-line-number="34"> lbl3 <span class="op">=</span> QLabel(<span class="st">&#39;for programmers&#39;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb1-35" data-line-number="35"> lbl3.move(<span class="dv">55</span>, <span class="dv">70</span>) </a>
<a class="sourceLine" id="cb1-36" data-line-number="36"></a>
<a class="sourceLine" id="cb1-37" data-line-number="37"> <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-38" data-line-number="38"> <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Absolute&#39;</span>) </a>
<a class="sourceLine" id="cb1-39" data-line-number="39"> <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb1-40" data-line-number="40"></a>
<a class="sourceLine" id="cb1-41" data-line-number="41"></a>
<a class="sourceLine" id="cb1-42" data-line-number="42"><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-43" data-line-number="43"></a>
<a class="sourceLine" id="cb1-44" data-line-number="44"> app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb1-45" data-line-number="45"> ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb1-46" data-line-number="46"> sys.exit(app.exec_())</a></code></pre></div>
<p>我们使用move()方法定位了每一个元素使用x、y坐标。x、y坐标的原点是程序的左上角。</p>
<pre><code class="language-python">lbl1 = QLabel(&#39;Zetcode&#39;, self)
lbl1.move(15, 10)</code></pre>
<p>这个元素的左上角就在这个程序的左上角开始的(15, 10)的位置。</p>
<p>程序展示:</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/3-absolute.png" alt="Absolute positioning" />
</figure>
<h2 id="盒布局">盒布局</h2>
<p>使用盒布局能让程序具有更强的适应性。这个才是布局一个应用的更合适的方式。<code>QHBoxLayout</code><code>QVBoxLayout</code>是基本的布局类,分别是水平布局和垂直布局。</p>
<p>如果我们需要把两个按钮放在程序的右下角,创建这样的布局,我们只需要一个水平布局加一个垂直布局的盒子就可以了。再用弹性布局增加一点间隙。</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 position two push</span></a>
<a class="sourceLine" id="cb3-8" data-line-number="8"><span class="co">buttons in the bottom-right corner </span></a>
<a class="sourceLine" id="cb3-9" data-line-number="9"><span class="co">of the window. </span></a>
<a class="sourceLine" id="cb3-10" data-line-number="10"></a>
<a class="sourceLine" id="cb3-11" data-line-number="11"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb3-12" data-line-number="12"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb3-13" data-line-number="13"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb3-14" data-line-number="14"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb3-15" data-line-number="15"></a>
<a class="sourceLine" id="cb3-16" data-line-number="16"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb3-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> (QWidget, QPushButton, </a>
<a class="sourceLine" id="cb3-18" data-line-number="18"> QHBoxLayout, QVBoxLayout, QApplication)</a>
<a class="sourceLine" id="cb3-19" data-line-number="19"></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">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb3-22" data-line-number="22"></a>
<a class="sourceLine" id="cb3-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="cb3-24" data-line-number="24"> <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb3-25" data-line-number="25"></a>
<a class="sourceLine" id="cb3-26" data-line-number="26"> <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb3-27" data-line-number="27"></a>
<a class="sourceLine" id="cb3-28" data-line-number="28"></a>
<a class="sourceLine" id="cb3-29" data-line-number="29"> <span class="kw">def</span> initUI(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb3-30" data-line-number="30"></a>
<a class="sourceLine" id="cb3-31" data-line-number="31"> okButton <span class="op">=</span> QPushButton(<span class="st">&quot;OK&quot;</span>)</a>
<a class="sourceLine" id="cb3-32" data-line-number="32"> cancelButton <span class="op">=</span> QPushButton(<span class="st">&quot;Cancel&quot;</span>)</a>
<a class="sourceLine" id="cb3-33" data-line-number="33"></a>
<a class="sourceLine" id="cb3-34" data-line-number="34"> hbox <span class="op">=</span> QHBoxLayout()</a>
<a class="sourceLine" id="cb3-35" data-line-number="35"> hbox.addStretch(<span class="dv">1</span>)</a>
<a class="sourceLine" id="cb3-36" data-line-number="36"> hbox.addWidget(okButton)</a>
<a class="sourceLine" id="cb3-37" data-line-number="37"> hbox.addWidget(cancelButton)</a>
<a class="sourceLine" id="cb3-38" data-line-number="38"></a>
<a class="sourceLine" id="cb3-39" data-line-number="39"> vbox <span class="op">=</span> QVBoxLayout()</a>
<a class="sourceLine" id="cb3-40" data-line-number="40"> vbox.addStretch(<span class="dv">1</span>)</a>
<a class="sourceLine" id="cb3-41" data-line-number="41"> vbox.addLayout(hbox)</a>
<a class="sourceLine" id="cb3-42" data-line-number="42"></a>
<a class="sourceLine" id="cb3-43" data-line-number="43"> <span class="va">self</span>.setLayout(vbox) </a>
<a class="sourceLine" id="cb3-44" data-line-number="44"></a>
<a class="sourceLine" id="cb3-45" data-line-number="45"> <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb3-46" data-line-number="46"> <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Buttons&#39;</span>) </a>
<a class="sourceLine" id="cb3-47" data-line-number="47"> <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb3-48" data-line-number="48"></a>
<a class="sourceLine" id="cb3-49" data-line-number="49"></a>
<a class="sourceLine" id="cb3-50" data-line-number="50"><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-51" data-line-number="51"></a>
<a class="sourceLine" id="cb3-52" data-line-number="52"> app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb3-53" data-line-number="53"> ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb3-54" data-line-number="54"> sys.exit(app.exec_())</a></code></pre></div>
<p>上面的例子完成了在应用的右下角放了两个按钮的需求。当改变窗口大小的时候,它们能依然保持在相对的位置。我们同时使用了<code>QHBoxLayout</code><code>QVBoxLayout</code></p>
<pre><code class="language-python">okButton = QPushButton(&quot;OK&quot;)
cancelButton = QPushButton(&quot;Cancel&quot;)</code></pre>
<p>这是创建了两个按钮。</p>
<pre><code class="language-python">hbox = QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(okButton)
hbox.addWidget(cancelButton)</code></pre>
<p>创建一个水平布局增加两个按钮和弹性空间。stretch函数在两个按钮前面增加了一些弹性空间。下一步我们把这些元素放在应用的右下角。</p>
<pre><code class="language-python">vbox = QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)</code></pre>
<p>为了布局需要,我们把这个水平布局放到了一个垂直布局盒里面。弹性元素会把所有的元素一起都放置在应用的右下角。</p>
<pre><code class="language-python">self.setLayout(vbox)</code></pre>
<p>最后,我们就得到了我们想要的布局。</p>
<p>程序预览:</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/3-buttons.png" alt="buttons" />
</figure>
<h2 id="栅格布局">栅格布局</h2>
<p>最常用的还是栅格布局了。这种布局是把窗口分为行和列。创建和使用栅格布局需要使用QGridLayout模块。</p>
<div class="sourceCode" id="cb8"><pre><code class="language-python"><a class="sourceLine" id="cb8-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb8-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb8-3" data-line-number="3"></a>
<a class="sourceLine" id="cb8-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb8-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb8-6" data-line-number="6"></a>
<a class="sourceLine" id="cb8-7" data-line-number="7"><span class="co">In this example, we create a skeleton</span></a>
<a class="sourceLine" id="cb8-8" data-line-number="8"><span class="co">of a calculator using a QGridLayout.</span></a>
<a class="sourceLine" id="cb8-9" data-line-number="9"></a>
<a class="sourceLine" id="cb8-10" data-line-number="10"><span class="co">author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb8-11" data-line-number="11"><span class="co">website: zetcode.com </span></a>
<a class="sourceLine" id="cb8-12" data-line-number="12"><span class="co">last edited: January 2015</span></a>
<a class="sourceLine" id="cb8-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb8-14" data-line-number="14"></a>
<a class="sourceLine" id="cb8-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb8-16" data-line-number="16"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> (QWidget, QGridLayout, </a>
<a class="sourceLine" id="cb8-17" data-line-number="17"> QPushButton, QApplication)</a>
<a class="sourceLine" id="cb8-18" data-line-number="18"></a>
<a class="sourceLine" id="cb8-19" data-line-number="19"></a>
<a class="sourceLine" id="cb8-20" data-line-number="20"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb8-21" data-line-number="21"></a>
<a class="sourceLine" id="cb8-22" data-line-number="22"> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb8-23" data-line-number="23"> <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb8-24" data-line-number="24"></a>
<a class="sourceLine" id="cb8-25" data-line-number="25"> <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb8-26" data-line-number="26"></a>
<a class="sourceLine" id="cb8-27" data-line-number="27"></a>
<a class="sourceLine" id="cb8-28" data-line-number="28"> <span class="kw">def</span> initUI(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb8-29" data-line-number="29"></a>
<a class="sourceLine" id="cb8-30" data-line-number="30"> grid <span class="op">=</span> QGridLayout()</a>
<a class="sourceLine" id="cb8-31" data-line-number="31"> <span class="va">self</span>.setLayout(grid)</a>
<a class="sourceLine" id="cb8-32" data-line-number="32"></a>
<a class="sourceLine" id="cb8-33" data-line-number="33"> names <span class="op">=</span> [<span class="st">&#39;Cls&#39;</span>, <span class="st">&#39;Bck&#39;</span>, <span class="st">&#39;&#39;</span>, <span class="st">&#39;Close&#39;</span>,</a>
<a class="sourceLine" id="cb8-34" data-line-number="34"> <span class="st">&#39;7&#39;</span>, <span class="st">&#39;8&#39;</span>, <span class="st">&#39;9&#39;</span>, <span class="st">&#39;/&#39;</span>,</a>
<a class="sourceLine" id="cb8-35" data-line-number="35"> <span class="st">&#39;4&#39;</span>, <span class="st">&#39;5&#39;</span>, <span class="st">&#39;6&#39;</span>, <span class="st">&#39;*&#39;</span>,</a>
<a class="sourceLine" id="cb8-36" data-line-number="36"> <span class="st">&#39;1&#39;</span>, <span class="st">&#39;2&#39;</span>, <span class="st">&#39;3&#39;</span>, <span class="st">&#39;-&#39;</span>,</a>
<a class="sourceLine" id="cb8-37" data-line-number="37"> <span class="st">&#39;0&#39;</span>, <span class="st">&#39;.&#39;</span>, <span class="st">&#39;=&#39;</span>, <span class="st">&#39;+&#39;</span>]</a>
<a class="sourceLine" id="cb8-38" data-line-number="38"></a>
<a class="sourceLine" id="cb8-39" data-line-number="39"> positions <span class="op">=</span> [(i,j) <span class="cf">for</span> i <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">5</span>) <span class="cf">for</span> j <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">4</span>)]</a>
<a class="sourceLine" id="cb8-40" data-line-number="40"></a>
<a class="sourceLine" id="cb8-41" data-line-number="41"> <span class="cf">for</span> position, name <span class="kw">in</span> <span class="bu">zip</span>(positions, names):</a>
<a class="sourceLine" id="cb8-42" data-line-number="42"></a>
<a class="sourceLine" id="cb8-43" data-line-number="43"> <span class="cf">if</span> name <span class="op">==</span> <span class="st">&#39;&#39;</span>:</a>
<a class="sourceLine" id="cb8-44" data-line-number="44"> <span class="cf">continue</span></a>
<a class="sourceLine" id="cb8-45" data-line-number="45"> button <span class="op">=</span> QPushButton(name)</a>
<a class="sourceLine" id="cb8-46" data-line-number="46"> grid.addWidget(button, <span class="op">*</span>position)</a>
<a class="sourceLine" id="cb8-47" data-line-number="47"></a>
<a class="sourceLine" id="cb8-48" data-line-number="48"> <span class="va">self</span>.move(<span class="dv">300</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb8-49" data-line-number="49"> <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Calculator&#39;</span>)</a>
<a class="sourceLine" id="cb8-50" data-line-number="50"> <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb8-51" data-line-number="51"></a>
<a class="sourceLine" id="cb8-52" data-line-number="52"></a>
<a class="sourceLine" id="cb8-53" data-line-number="53"><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="cb8-54" data-line-number="54"></a>
<a class="sourceLine" id="cb8-55" data-line-number="55"> app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb8-56" data-line-number="56"> ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb8-57" data-line-number="57"> sys.exit(app.exec_())</a></code></pre></div>
<p>这个例子里,我们创建了栅格化的按钮。</p>
<pre><code class="language-python">grid = QGridLayout()
self.setLayout(grid)</code></pre>
<p>创建一个QGridLayout实例并把它放到程序窗口里。</p>
<pre><code class="language-python">names = [&#39;Cls&#39;, &#39;Bck&#39;, &#39;&#39;, &#39;Close&#39;,
&#39;7&#39;, &#39;8&#39;, &#39;9&#39;, &#39;/&#39;,
&#39;4&#39;, &#39;5&#39;, &#39;6&#39;, &#39;*&#39;,
&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;-&#39;,
&#39;0&#39;, &#39;.&#39;, &#39;=&#39;, &#39;+&#39;]</code></pre>
<p>这是我们将要使用的按钮的名称。</p>
<pre><code class="language-python">positions = [(i,j) for i in range(5) for j in range(4)]</code></pre>
<p>创建按钮位置列表。</p>
<pre><code class="language-python">for position, name in zip(positions, names):
if name == &#39;&#39;:
continue
button = QPushButton(name)
grid.addWidget(button, *position)</code></pre>
<p>创建按钮,并使用<code>addWidget()</code>方法把按钮放到布局里面。</p>
<p>程序预览:</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/3-calculator.png" alt="Calculator skeleton" />
</figure>
<h2 id="制作提交反馈信息的布局">制作提交反馈信息的布局</h2>
<p>组件能跨列和跨行展示,这个例子里,我们就试试这个功能。</p>
<div class="sourceCode" id="cb13"><pre><code class="language-python"><a class="sourceLine" id="cb13-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb13-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb13-3" data-line-number="3"></a>
<a class="sourceLine" id="cb13-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb13-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb13-6" data-line-number="6"></a>
<a class="sourceLine" id="cb13-7" data-line-number="7"><span class="co">In this example, we create a more </span></a>
<a class="sourceLine" id="cb13-8" data-line-number="8"><span class="co">complicated window layout using</span></a>
<a class="sourceLine" id="cb13-9" data-line-number="9"><span class="co">the QGridLayout manager. </span></a>
<a class="sourceLine" id="cb13-10" data-line-number="10"></a>
<a class="sourceLine" id="cb13-11" data-line-number="11"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb13-12" data-line-number="12"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb13-13" data-line-number="13"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb13-14" data-line-number="14"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb13-15" data-line-number="15"></a>
<a class="sourceLine" id="cb13-16" data-line-number="16"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb13-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> (QWidget, QLabel, QLineEdit, </a>
<a class="sourceLine" id="cb13-18" data-line-number="18"> QTextEdit, QGridLayout, QApplication)</a>
<a class="sourceLine" id="cb13-19" data-line-number="19"></a>
<a class="sourceLine" id="cb13-20" data-line-number="20"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb13-21" data-line-number="21"></a>
<a class="sourceLine" id="cb13-22" data-line-number="22"> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb13-23" data-line-number="23"> <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb13-24" data-line-number="24"></a>
<a class="sourceLine" id="cb13-25" data-line-number="25"> <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb13-26" data-line-number="26"></a>
<a class="sourceLine" id="cb13-27" data-line-number="27"></a>
<a class="sourceLine" id="cb13-28" data-line-number="28"> <span class="kw">def</span> initUI(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb13-29" data-line-number="29"></a>
<a class="sourceLine" id="cb13-30" data-line-number="30"> title <span class="op">=</span> QLabel(<span class="st">&#39;Title&#39;</span>)</a>
<a class="sourceLine" id="cb13-31" data-line-number="31"> author <span class="op">=</span> QLabel(<span class="st">&#39;Author&#39;</span>)</a>
<a class="sourceLine" id="cb13-32" data-line-number="32"> review <span class="op">=</span> QLabel(<span class="st">&#39;Review&#39;</span>)</a>
<a class="sourceLine" id="cb13-33" data-line-number="33"></a>
<a class="sourceLine" id="cb13-34" data-line-number="34"> titleEdit <span class="op">=</span> QLineEdit()</a>
<a class="sourceLine" id="cb13-35" data-line-number="35"> authorEdit <span class="op">=</span> QLineEdit()</a>
<a class="sourceLine" id="cb13-36" data-line-number="36"> reviewEdit <span class="op">=</span> QTextEdit()</a>
<a class="sourceLine" id="cb13-37" data-line-number="37"></a>
<a class="sourceLine" id="cb13-38" data-line-number="38"> grid <span class="op">=</span> QGridLayout()</a>
<a class="sourceLine" id="cb13-39" data-line-number="39"> grid.setSpacing(<span class="dv">10</span>)</a>
<a class="sourceLine" id="cb13-40" data-line-number="40"></a>
<a class="sourceLine" id="cb13-41" data-line-number="41"> grid.addWidget(title, <span class="dv">1</span>, <span class="dv">0</span>)</a>
<a class="sourceLine" id="cb13-42" data-line-number="42"> grid.addWidget(titleEdit, <span class="dv">1</span>, <span class="dv">1</span>)</a>
<a class="sourceLine" id="cb13-43" data-line-number="43"></a>
<a class="sourceLine" id="cb13-44" data-line-number="44"> grid.addWidget(author, <span class="dv">2</span>, <span class="dv">0</span>)</a>
<a class="sourceLine" id="cb13-45" data-line-number="45"> grid.addWidget(authorEdit, <span class="dv">2</span>, <span class="dv">1</span>)</a>
<a class="sourceLine" id="cb13-46" data-line-number="46"></a>
<a class="sourceLine" id="cb13-47" data-line-number="47"> grid.addWidget(review, <span class="dv">3</span>, <span class="dv">0</span>)</a>
<a class="sourceLine" id="cb13-48" data-line-number="48"> grid.addWidget(reviewEdit, <span class="dv">3</span>, <span class="dv">1</span>, <span class="dv">5</span>, <span class="dv">1</span>)</a>
<a class="sourceLine" id="cb13-49" data-line-number="49"></a>
<a class="sourceLine" id="cb13-50" data-line-number="50"> <span class="va">self</span>.setLayout(grid) </a>
<a class="sourceLine" id="cb13-51" data-line-number="51"></a>
<a class="sourceLine" id="cb13-52" data-line-number="52"> <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">350</span>, <span class="dv">300</span>)</a>
<a class="sourceLine" id="cb13-53" data-line-number="53"> <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Review&#39;</span>) </a>
<a class="sourceLine" id="cb13-54" data-line-number="54"> <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb13-55" data-line-number="55"></a>
<a class="sourceLine" id="cb13-56" data-line-number="56"></a>
<a class="sourceLine" id="cb13-57" data-line-number="57"><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="cb13-58" data-line-number="58"></a>
<a class="sourceLine" id="cb13-59" data-line-number="59"> app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb13-60" data-line-number="60"> ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb13-61" data-line-number="61"> sys.exit(app.exec_())</a></code></pre></div>
<p>我们创建了一个有三个标签的窗口。两个行编辑和一个文版编辑,这是用<code>QGridLayout</code>模块搞定的。</p>
<pre><code class="language-python">grid = QGridLayout()
grid.setSpacing(10)</code></pre>
<p>创建标签之间的空间。</p>
<pre><code class="language-python">grid.addWidget(reviewEdit, 3, 1, 5, 1)</code></pre>
<p>我们可以指定组件的跨行和跨列的大小。这里我们指定这个元素跨5行显示。</p>
<p>程序预览:</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/3-review.png" alt="review example" />
</figure>