Python中有许多GUI模块可以用于开发GUI程序。最简单的有Turtle,然而它并不能用来创建图形用户界面。用于开发GUI的库主要有以下几种:
这里主要介绍Tkinter
from tkinter import *
window = Tk() #创建一个窗口
label = Label(window, text = "Wellcome to Python") # 创建一个带文本的标签
button = Button(window, text = "Click Me") # 创建一个按钮
label.pack() # 把标签放在窗口中
button.pack() # 把按钮放在窗口中
# 包管理器将小构件一行一行地放在窗口之中
window.mainloop() # 创建一个事件循环,持续处理事件直到关闭主窗口
from tkinter import *
def processOK(): # 回调函数
print("OK button is clicked")
def processCancel():
print("Cancel button is clicked")
window = Tk()
btOK = Button(window, text = "OK", fg = "red", command = processOK)
btCancel = Button(window, text = "Cancel", bg = "yellow",
command = processCancel)
# fg前景色(文字颜色),默认黑色
# bg背景色(背景颜色),默认灰色
btOK.pack()
btCancel.pack()
window.mainloop()
将函数放到类中:
from tkinter import *
class ProcessButtonEvent:
"""docstring for ProcessButtonEvent"""
def __init__(self):
window = Tk()
btOK = Button(window, text = "OK", fg = "red",
command = self.processOK)
btCancel = Button(window, text = "Cancel", bg = "yellow",
command = self.processCancel)
btOK.pack()
btCancel.pack()
window.mainloop()
def processOK(self): # 回调函数
print("OK button is clicked")
def processCancel(self):
print("Cancel button is clicked")
ProcessButtonEvent()
Tkinter中的小部件如下:
Button
按钮Canvas
画布CheckButton
复选框Entry
输入框Frame
容器,可将其他小部件放到里面Label
显示文本或图像Menu
实现下拉菜单或弹出菜单的菜单栏Menubutton
下拉菜单项Message
类似Label,但是能自动将文本放置在给定的宽度或宽高比内Radiobutton
单选框Text
格式化的文本显示,允许不同风格和属性显示和编辑文本,也支持内嵌的图片和窗口一些属性:
justify
属性改变对齐方式,如 LEFT
, RIGHT
, CENTER
cursor
光标的形状设定:可以设置 cursor
选项指定光标形状,如arrow
, circle
, cross
, plus
等示例如下:
from tkinter import *
class WidgetsDemo:
"""docstring for ClassName"""
def __init__(self):
window = Tk()
window.title("Widgets Demmo")
frame1 = Frame(window)
frame1.pack()
self.v1 = IntVar()
cbtBold = Checkbutton(frame1, text = "Bold", variable = self.v1,
command = self.processCheckbutton)
self.v2 = IntVar()
# value为当radiobutton被点击时 v1 的取值
rbRed = Radiobutton(frame1, text = "Red", bg = "red",
variable = self.v2, value = 1,
command = self.processRadiobutton)
rbYellow = Radiobutton(frame1, text = "Yellow", bg= "yellow",
variable = self.v2, value = 2,
command = self.processRadiobutton)
cbtBold.grid(row = 1, column = 1)
rbRed.grid(row = 1, column = 2)
rbYellow.grid(row = 1, column = 3)
frame2 = Frame(window)
frame2.pack()
label = Label(frame2, text = "Enter your name: ")
self.name = StringVar()
entryName = Entry(frame2, textvariable = self.name)
btGetName = Button(frame2, text = "Get Name",
command = self.processButton)
message = Message(frame2, text = "It is widgets demo")
label.grid(row = 1, column = 1)
entryName.grid(row = 1, column = 2)
btGetName.grid(row = 1, column = 3)
message.grid(row = 1, column = 4)
text = Text(window)
text.pack()
# END 表示文本被插入到当前内容的结尾
text.insert(END, "Tip\nThe best way to learn Tkinter is to read ")
text.insert(END, "these carefully designed examples and use them ")
text.insert(END, "to create your applications. ")
window.mainloop()
def processCheckbutton(self):
print("check button is "
+ ("checked " if self.v1.get() == 1 else "unckecked "))
def processRadiobutton(self):
print(("Red" if self.v2.get() == 1 else "Yellow") + " is selected")
def processButton(self):
print("Your name is " + self.name.get())
WidgetsDemo()
改变Label的值:
from tkinter import *
class ChangeLabelDemo:
"""docstring for ChangeLabelDemo"""
def __init__(self):
window = Tk()
window.title()
frame1 = Frame(window)
frame1.pack()
self.lbl = Label(frame1, text = "Programming is fun")
self.lbl.pack()
frame2 = Frame(window)
frame2.pack()
label = Label(frame2, text = "Enter text: ")
self.msg = StringVar()
entry = Entry(frame2, textvariable = self.msg)
btChangeText = Button(frame2, text = "Change Text",
command = self.processButton)
self.v1 = IntVar()
rbRed = Radiobutton(frame2, text = "Red", bg = "red",
variable = self.v1, value = 1,
command = self.processRadiobutton)
rbYellow = Radiobutton(frame2, text = "Yellow", bg = "yellow",
variable = self.v1, value = 2,
command = self.processRadiobutton)
label.grid(row = 1, column = 1)
entry.grid(row = 1, column = 2)
btChangeText.grid(row = 1, column = 3)
rbRed.grid(row = 1, column = 4)
rbYellow.grid(row = 1, column =5)
window.mainloop()
def processRadiobutton(self):
if self.v1.get() == 1:
self.lbl["fg"] = "red"
elif self.v1.get() == 2:
self.lbl['fg'] = "yellow"
def processButton(self):
self.lbl['text'] = self.msg.get()
ChangeLabelDemo()
from tkinter import *
class CanvasDemo:
def __init__(self):
window = Tk()
window.title("Canvas Demo")
self.canvas = Canvas(window, width = 200, height = 100, bg = "white")
self.canvas.pack()
frame = Frame(window)
frame.pack()
btRectangle = Button(frame, text = "Rectangele",
command = self.displayRect)
btOval = Button(frame, text = "Oval",
command = self.displayOval)
btArc = Button(frame, text = "Arc",
command = self.displayArc)
btPolygon = Button(frame, text = "Polygon",
command = self.displayPolygon)
btLine = Button(frame, text = "Line",
command = self.displayLine)
btString = Button(frame, text = "String",
command = self.displayString)
btClear = Button(frame, text = "ClearClear",
command = self.clearCanvas)
btRectangle.grid(row = 1, column = 1)
btOval.grid(row = 1, column = 2)
btArc.grid(row = 1, column = 3)
btPolygon.grid(row = 1, column = 4)
btLine.grid(row = 1, column = 5)
btString.grid(row = 1, column = 6)
btClear.grid(row = 1, column = 7)
window.mainloop()
def displayRect(self):
self.canvas.create_rectangle(10, 10, 190, 90, tags = "rect")
def displayOval(self):
self.canvas.create_oval(10, 10, 190, 90, fill = "red", tags = "oval")
def displayArc(self):
self.canvas.create_arc(10, 10, 190, 90, start = 0, extent = 90,
width = 8, fill = "red", tags = "arc")
def displayPolygon(self):
self.canvas.create_polygon(10, 10, 190, 90, 30, 50, tags = "polygon")
# arrow 绘制箭头
# activefill 鼠标经过时的颜色
def displayLine(self):
self.canvas.create_line(10, 10, 190, 90, fill = "red", tags = "line")
self.canvas.create_line(10, 90, 190, 10, width = 9, arrow = "last",
activefill = "blue", tags = "line")
def displayString(self):
self.canvas.create_text(60, 40, text = "Hi, I am a string",
font = "Times 10 bold underline", tags = "string")
# 根据 tag 来删除图像
def clearCanvas(self):
self.canvas.delete("rect", "oval", "arc", "polygon", "line",
"string")
CanvasDemo()
网格管理器:按网格单元放置。
包管理器:让部件按一个方向放置
pack中可指设置side选项来制定小组件的放置方法,如LEFT、RIGHT、TOP、BOTTOM
from tkinter import *
class PackManagerDemo:
def __init__(self):
window = Tk()
window.title("Pack Manager Demo")
Label(window, text = "Blue", bg = "blue").pack()
# 如果父控件比所容纳的子控件所需空间大,那么给 expand =1 的子控件分配额外的空间
# side选项定义控件的摆放方式,有:LEFT, RIGHT, TOP, BOTTOM
Label(window, text = "Red", bg = "red").pack(fill = BOTH, expand = 1)
Label(window, text = "Green", bg = "green").pack(fill = BOTH)
window.mainloop()
PackManagerDemo()
from tkinter import *
class MenuDemo:
''' 顶部菜单和右键菜单的实现 '''
def __init__(self):
window = Tk()
window.title("Menu Demo")
menubar = Menu(window) # 新建菜单
window.config(menu = menubar)
operationMenu = Menu(menubar, tearoff = 0) # 菜单项operationMenu
menubar.add_cascade(label = "Operation", menu = operationMenu)
operationMenu.add_command(label = "Add", command = self.add)
operationMenu.add_command(label = "Sub", command = self.sub)
operationMenu.add_command(label = "Mul", command = self.mul)
operationMenu.add_command(label = "Div", command = self.div)
exitmenu = Menu(menubar, tearoff = 0) # 菜单项exitmenu
menubar.add_cascade(label = "Exit", menu = exitmenu)
exitmenu.add_command(label = "Quit", command = window.quit)
self.lbl = Label(window, text = "Menu Test")
self.lbl.pack()
# 弹出菜单
self.menu = Menu(window, tearoff = 0)
self.menu.add_command(label = "Draw line", command = self.displayLine)
self.menu.add_command(label = "Draw Oval", command = self.diaplayOval)
self.menu.add_command(label = "Draw rect", command = self.diaplayRect)
self.menu.add_command(label = "Clear", command = self.clearCanvas)
self.canvas = Canvas(window, width = 200, height = 100, bg = "white")
self.canvas.pack()
# 绑定右键点击事件,用popup()函数处理
self.canvas.bind("", self.popup)
window.mainloop()
def add(self):
self.lbl["text"] = "add"
def sub(self):
self.lbl["text"] = "sub"
def mul(self):
self.lbl["text"] = "mul"
def div(self):
self.lbl["text"] = "div"
def displayLine(self):
self.canvas.create_line(10, 10, 190, 90, tags = "line")
self.canvas.create_line(10, 90, 190, 10, tags = "line")
def diaplayOval(self):
self.canvas.create_oval(10, 10, 190, 90, tags = "oval")
def diaplayRect(self):
self.canvas.create_rectangle(10, 10, 190, 90, tags = "rect")
def clearCanvas(self):
self.canvas.delete("line", "oval", "rect")
def popup(self, event):
self.menu.post(event.x_root, event.y_root)
MenuDemo()
事件列表:
鼠标被按住并移动
单击鼠标动作。i 取值为1、2、3,分别为左键、中键、右键
鼠标按键释放
鼠标按键双击
鼠标光标计进入
单击一个键
鼠标光标离开
单击Enter键
三连击Event对象的属性:
char
按键字符keycode
按键的统一码keysym
按键字符num
鼠标的按键,为0、1、2widget
事件产生的小构件对象x
和 y
鼠标在构件中的位置x_root
和 y_root
鼠标相对于屏幕左上角的位置示例如下:
from tkinter import *
class MouseKeyEventDemo:
def __init__(self):
window = Tk()
window.title("Event Demo")
canvas = Canvas(window, bg = "white", width = 200, height = 100)
canvas.pack()
canvas.bind("", self.processMouseEvent)
canvas.bind("", self.processKeyEvent)
canvas.focus()
window.mainloop()
def processMouseEvent(self, event):
print("Cliked at: ", event.x, event.y)
print("Position in the screen: ", event.x_root, event.y_root)
print("Which button is clicked? ", event.num)
def processKeyEvent(self, event):
print("Keysym? ", event.keysym)
print("char? ", event.char)
print("keycode? ", event.keycode)
MouseKeyEventDemo()
from tkinter import *
class ProcessButtonEvent:
"""docstring for ProcessButtonEvent"""
def __init__(self):
window = Tk()
btOK = Button(window, text = "OK", fg = "red",
command = self.processOK)
btCancel = Button(window, text = "Cancel", bg = "yellow",
command = self.processCancel)
btOK.pack()
btCancel.pack()
window.mainloop()
def processOK(self): # 回调函数
print("OK button is clicked")
def processCancel(self):
print("Cancel button is clicked")
ProcessButtonEvent()