Python图形用户界面

来源:互联网 发布:linux内核设计及实现 编辑:程序博客网 时间:2024/06/05 03:27

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中的可变类型

不可变类型可变类型intIntVarstringStringVarboolBooleanVardoubleDoubleVar

模型、视图、控制器

顾名思义,视图用于把信息显示给用户;模型则只是存储数据;控制器则可以更新应用程序的模型,并进而出发相应的视图发生变化。

如下例子实现点击按钮之后标签上的计数增加:

<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>
0 0