图形用户界面 python_Python图形用户界面

tkinter是Python中可用于构建GUI的众多工具集之一。

# tkinter模块

~~~

# 可以使用import tkinter as tk并通过tk.thing去引用其中的内容

from tkinter import *

window = Tk()

window.mainloop()

~~~

以上代码可以显示一个空白的根窗口。可以将其看成是应用程序的最外层容器,创建其他插件(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 |

# 模型、视图、控制器

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

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

~~~

from tkinter import *

# The controller.

def click():

counter.set(counter.get() + 1)

if __name__ == '__main__':

# More initialization

window = Tk()

# The model.

counter = IntVar()

counter.set(0)

# The views.

frame = Frame(window)

frame.pack()

button = Button(frame, text='Click', command=click)

button.pack()

label = Label(frame, textvariable=counter)

label.pack()

window.mainloop()

~~~

### 使用Lambda

如果我们不仅希望能增加counter的值,还希望能降低它的值。则我们需要添加另一个按钮和另一个控制器函数。代码如下:

~~~

from tkinter import *

# The controller.

def click_up():

counter.set(counter.get() + 1)

def click_down():

counter.set(counter.get() - 1)

if __name__ == '__main__':

# More initialization

window = Tk()

# The model.

counter = IntVar()

counter.set(0)

# The views.

frame = Frame(window)

frame.pack()

button = Button(frame, text='Up', command=click_up)

button.pack()

button = Button(frame, text='Down', command=click_down)

button.pack()

label = Label(frame, textvariable=counter)

label.pack()

window.mainloop()

~~~

上述实现代码看起来有点傻,`click_up`和`click_down`做的事情看起来几乎是一样的,应该将它们合成一个。这时,我们应该显示的把counter传递给函数,而不是使用全局变量。

~~~

# The model.

counter = IntVar()

counter.set(0)

# One controller with parameters

def click(variable, value):

varaible.set(variable.get() + value)

~~~

tkinter要求由按钮(以及别的插件)出发的控制器函数不能含有参数,目的就是为了以同一种方式去调用它们。我们要做的事情就是:对这个带有两个参数的函数进行处理,使其变成一个不带参数的函数。

一个好一点的做法是使用lambda函数,它使我们能够创建一个没有名字的单行函数。

~~~

from tkinter import *

window = Tk()

# The model

counter = IntVar()

counter.set(0)

# General controller.

def click(var, value):

var.set(var.get() + value)

# The views.

frame = Frame(window)

frame.pack()

button = Button(frame, text='Up', command=lambda: click(counter, 1))

button.pack()

button = Button(frame, text='Down', command=lambda: click(counter, -1))

button.pack()

label = Label(frame, textvariable=counter)

label.pack()

window.mainloop()

~~~

这段代码分别为两个按钮创建了一个不带参数的lambda函数,这两个lambda函数会将正确的值传进click。

# 样式

~~~

from tkinter import *

window = Tk()

# 字体

button = Button(window, text='hello', font=('Courier', 14, 'bold italic'))

# 布局

button.pack(side='left')

# 颜色

label = Label(window, text='hello', bg='green', fg='white')

label.pack()

window.mainloop()

~~~

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

~~~

from tkinter import *

window = Tk()

button = Button(window, text='button1', font=('Courier', 14, 'bold italic'))

button.grid(row=0, column=0)

label = Label(window, text='label1', bg='green', fg='white')

label.grid(row=0, column=1)

label = Label(window, text='label2', bg='green', fg='white')

label.grid(row=1, column=1)

window.mainloop()

~~~

可以使用rowspan和columnspan设置插件所占据的行数,默认为1。

# 面向对象的GUI

几乎所有真实的GUI都是以类和对象来建造的:他们讲模型、视图和控制器一起放到一个干净整洁的包(package)中。例如下面的计数器函数,其模型是Counter类的一个名为`self.state`的成员变量,其控制器是`upClick`和`quitClick`方法。

~~~

from tkinter import *

class Counter:

'''A simple counter GUI using object-oriented programming.'''

def __init__(self, parent):

'''Create the GUI.'''

# Framework.

self.parent = parent

self.frame = Frame(parent)

self.frame.pack()

# Model.

self.state = IntVar()

self.state.set(1)

# Label displaying current state.

self.label = Label(self.frame, textvariable=self.state)

self.label.pack()

# Buttons to control application.

self.up = Button(self.frame, text='up', command=self.upClick)

self.up.pack(side='left')

self.right = Button(self.frame, text='quit', command=self.quitClick)

self.right.pack(side='left')

def upClick(self):

'''Handle click on 'up' button.'''

self.state.set(self.state.get() + 1)

def quitClick(self):

'''Handle click on 'quit' button.'''

self.parent.destroy()

if __name__ == '__main__':

window = Tk()

myapp = Counter(window)

window.mainloop()

~~~

参考资料:

《Python编程实践》

《Practical Programming An Introduction to Computer Science Using Python》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值