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>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值