tkinter是Python中可用于构建GUI的众多工具集之一。
<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>
如果我们不仅希望能增加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_up
和click_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都是以类和对象来建造的:他们讲模型、视图和控制器一起放到一个干净整洁的包(package)中。例如下面的计数器函数,其模型是Counter类的一个名为self.state
的成员变量,其控制器是upClick
和quitClick
方法。
<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>