Python圖形用戶界面

tkinter是Python中可用於構建GUI的衆多工具集之一。

tkinter模塊

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 可以使用import tkinter as tk並通過tk.thing去引用其中的內容</span>
from tkinter <span class="hljs-reserved" style="box-sizing: border-box;">import</span> *

<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">window</span> = Tk()
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">window</span>.mainloop()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

以上代碼可以顯示一個空白的根窗口。可以將其看成是應用程序的最外層容器,創建其他插件(widget)的時候就需要用到它。如果關閉屏幕上的窗口,則相應的窗口對象就會被銷燬。所有的應用程序都只有一個主窗口;此外,還可以通過TopLevel這個小插件來創建額外的窗口。

tkinter小插件包括Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menu, Message, Menubutton, Text, TopLevel等。

可變的變量

在Python中字符串、整數、浮點數以及布爾值都是不可變的,於是tkinter自帶了一些類型;他們可以就地更新,並可以在其值發生變化時通知相關的插件。

tkinter中的可變類型

不可變類型 可變類型
int IntVar
string StringVar
bool BooleanVar
double DoubleVar

模型、視圖、控制器

顧名思義,視圖用於把信息顯示給用戶;模型則只是存儲數據;控制器則可以更新應用程序的模型,並進而出發相應的視圖發生變化。

如下例子實現點擊按鈕之後標籤上的計數增加:

<code class="hljs python has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> tkinter <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> *

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># The controller.</span>
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">click</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>:</span>
    counter.set(counter.get() + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> __name__ == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'__main__'</span>:
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># More initialization</span>
    window = Tk()

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># The model.</span>
    counter = IntVar()
    counter.set(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># The views.</span>
    frame = Frame(window)
    frame.pack()

    button = Button(frame, text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Click'</span>, command=click)
    button.pack()

    label = Label(frame, textvariable=counter)
    label.pack()

    window.mainloop()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

使用Lambda

如果我們不僅希望能增加counter的值,還希望能降低它的值。則我們需要添加另一個按鈕和另一個控制器函數。代碼如下:

<code class="hljs python has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> tkinter <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> *

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># The controller.</span>
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">click_up</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>:</span>
    counter.set(counter.get() + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)

<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">click_down</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>:</span>
    counter.set(counter.get() - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)


<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> __name__ == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'__main__'</span>:
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># More initialization</span>
    window = Tk()

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># The model.</span>
    counter = IntVar()
    counter.set(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># The views.</span>
    frame = Frame(window)
    frame.pack()

    button = Button(frame, text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Up'</span>, command=click_up)
    button.pack()

    button = Button(frame, text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Down'</span>, command=click_down)
    button.pack()

    label = Label(frame, textvariable=counter)
    label.pack()

    window.mainloop()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li></ul>

上述實現代碼看起來有點傻,click_upclick_down做的事情看起來幾乎是一樣的,應該將它們合成一個。這時,我們應該顯示的把counter傳遞給函數,而不是使用全局變量。

<code class="hljs python has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># The model.</span>
counter = IntVar()
counter.set(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># One controller with parameters</span>
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">click</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(variable, value)</span>:</span>
    varaible.set(variable.get() + value)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

tkinter要求由按鈕(以及別的插件)出發的控制器函數不能含有參數,目的就是爲了以同一種方式去調用它們。我們要做的事情就是:對這個帶有兩個參數的函數進行處理,使其變成一個不帶參數的函數。

一個好一點的做法是使用lambda函數,它使我們能夠創建一個沒有名字的單行函數。

<code class="hljs python has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> tkinter <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> *
window = Tk()

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># The model</span>
counter = IntVar()
counter.set(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># General controller.</span>
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">click</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(var, value)</span>:</span>
    var.set(var.get() + value)

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># The views.</span>
frame = Frame(window)
frame.pack()

button = Button(frame, text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Up'</span>, command=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">lambda</span>: click(counter, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>))
button.pack()

button = Button(frame, text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Down'</span>, command=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">lambda</span>: click(counter, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>))
button.pack()

label = Label(frame, textvariable=counter)
label.pack()

window.mainloop()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

這段代碼分別爲兩個按鈕創建了一個不帶參數的lambda函數,這兩個lambda函數會將正確的值傳進click。

樣式

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">from tkinter <span class="hljs-reserved" style="box-sizing: border-box;">import</span> *
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">window</span> = Tk()

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 字體</span>
button = Button(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">window</span>, text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'hello'</span>, font=(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Courier'</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">14</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'bold italic'</span>))
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 佈局</span>
button.pack(side=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'left'</span>)

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 顏色</span>
label = Label(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">window</span>, text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'hello'</span>, bg=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'green'</span>, fg=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'white'</span>)
label.pack()

<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">window</span>.mainloop()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

控制佈局,就可以使用pack,也可以使用grid,但是不能兩者都用。

<code class="hljs mel has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">from tkinter import *
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">window</span> = Tk()

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">button</span> = Button(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">window</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">text</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'button1'</span>, font=(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'Courier'</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">14</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'bold italic'</span>))
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">button</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">grid</span>(row=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, column=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)

label = Label(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">window</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">text</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'label1'</span>, bg=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'green'</span>, fg=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'white'</span>)
label.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">grid</span>(row=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, column=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)

label = Label(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">window</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">text</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'label2'</span>, bg=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'green'</span>, fg=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'white'</span>)
label.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">grid</span>(row=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, column=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">window</span>.mainloop()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

可以使用rowspan和columnspan設置插件所佔據的行數,默認爲1。

面向對象的GUI

幾乎所有真實的GUI都是以類和對象來建造的:他們講模型、視圖和控制器一起放到一個乾淨整潔的包(package)中。例如下面的計數器函數,其模型是Counter類的一個名爲self.state的成員變量,其控制器是upClickquitClick方法。

<code class="hljs python has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> tkinter <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> *

<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Counter</span>:</span>
    <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'''A simple counter GUI using object-oriented programming.'''</span>

    <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">__init__</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(self, parent)</span>:</span>
        <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'''Create the GUI.'''</span>

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># Framework.</span>
        self.parent = parent
        self.frame = Frame(parent)
        self.frame.pack()

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># Model.</span>
        self.state = IntVar()
        self.state.set(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># Label displaying current state.</span>
        self.label = Label(self.frame, textvariable=self.state)
        self.label.pack()

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># Buttons to control application.</span>
        self.up = Button(self.frame, text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'up'</span>, command=self.upClick)
        self.up.pack(side=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'left'</span>)

        self.right = Button(self.frame, text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'quit'</span>, command=self.quitClick)
        self.right.pack(side=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'left'</span>)

    <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">upClick</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(self)</span>:</span>
        <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'''Handle click on 'up' button.'''</span>
        self.state.set(self.state.get() + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)

    <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">quitClick</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(self)</span>:</span>
        <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'''Handle click on 'quit' button.'''</span>
        self.parent.destroy()

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> __name__ == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'__main__'</span>:
    window = Tk()
    myapp = Counter(window)
    window.mainloop()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li></ul>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章