canvas画图
方法 | 说明 | 参数 |
.create_line() | 画线 | 起点坐标,终点坐标,width=线宽,fill=颜色 |
.create_arc() | 画弧线 | 起点坐标,终点坐标,width=线宽,fill=颜色 |
.create_rectangle() | 画矩形 | 起点坐标,终点坐标,fill=‘填充的颜色’,outline=边框颜色 |
.create_oval() | 画椭圆 | 外界矩阵的左上角和右小角坐标,fill=‘填充的颜色’,outline=边框颜色 |
.create_polygon() | 画多边形 | 多点坐标,fill=‘填充的颜色’,outline=边框颜色 |
.create_text() | 显示文字 | text=‘文字’ |
.delete() | 删除对象 | |
.move() | 移动 | (参数,0,2)横向不移动,纵向移动2 |
.update() | 更新 | 当应用程序的状态发生变化和需要这些变化立刻显示时,不用等待脚本完成 |
.pack() | 包装 |
eg.canvas画布
import tkinter as tk
win = tk.Tk()
win.geometry("600x400+200+100")
canvas = tk.Canvas(win, bg="white")
canvas.place(relx=0.05, rely=0.05, relwidth=0.9, relheight=0.9)
# 画一条实线, fill:填充的颜色
line1 = canvas.create_line((0, 10), (50, 50), width=5, fill="green")
# 画一条虚线 dash=(1, 1)
canvas.create_line((200, 200), (200, 300), width=5, fill="green", dash=(1, 1))
# 画一个圆弧
canvas.create_arc((100, 100), (200, 200), width=5)
# 显示文字
canvas.create_text((300, 100), text="canvas画布", font=("微软雅黑", 18))
# 绘制矩形, outline:线条颜色
canvas.create_rectangle(50, 25, 150, 75, fill='blue', outline='green', width=5)
# 绘制椭圆
canvas.create_oval(200, 25, 350, 75, fill='pink', outline='green', width=5)
# 绘制多边形
point = [(0, 0), (150, 200), (200, 300), (300, 450), (450, 550)]
canvas.create_polygon(point, outline='green', fill='yellow')
def dele_line():
canvas.delete(line1)
btn = tk.Button(canvas, text="删除", command=dele_line)
btn.place(relx=0.4, rely=0.8)
win.mainloop()
运行结果:
from tkinter import *
import hashlib
root = Tk()
w = Canvas(root,width=200,height=100)
w.pack()
line1 = w.create_line(0,50,200,50,fill='black')
line2 = w.create_line(100,0,100,100,fill='red',dash=(4,4))
rect1 = w.create_rectangle(50,25,150,75,fill='blue')
#修改位置
w.coords(line1,0,25,200,25)
# 修改选项
w.itemconfig(rect1,fill='red')
w.delete(line2)
Button(root,text="删除全部",command=(lambda x=ALL:w.delete(x))).pack()
mainloop()
eg.五子棋盘
import tkinter
def mouse_evt_handler(evt=None):
print(evt.x,evt.y)
# margin=20
row = round((evt.y - 20) / 40)
col = round((evt.x - 20) / 40)
pos_x = 40 * col
pos_y = 40 * row
print(pos_x, pos_y, 40 + pos_x, 40 + pos_y)
# 圆外矩形左上角与右下角坐标
canvas.create_oval(pos_x, pos_y, 40 + pos_x, 40 + pos_y, fill='black')
top = tkinter.Tk()
# 设置窗口尺寸
top.geometry('620x620')
# 设置窗口标题
top.title('五子棋')
# 设置窗口大小不可改变
top.resizable(False, False)
# 设置窗口置顶
top.wm_attributes('-topmost', 1)
canvas = tkinter.Canvas(top, width=600, height=600, bd=0, highlightthickness=0)
# 鼠标左键绑定点击事件
canvas.bind('<Button-1>', mouse_evt_handler)
canvas.create_rectangle(0, 0, 600, 600, fill='b99e20', outline='white')
for index in range(15):
canvas.create_line(20, 20 + 40 * index, 580, 20 + 40 * index, fill='black')
canvas.create_line(20 + 40 * index, 20, 20 + 40 * index, 580, fill='black')
canvas.create_rectangle(15, 15, 585, 585, outline='black', width=4)
canvas.pack()
tkinter.mainloop()
运行结果:
说明:五子棋对弈过程待实现。
eg.动态动画
import tkinter
import time
# 播放动画效果的函数
def play_animation():
canvas.move(oval, 2, 2)
canvas.update()
top.after(50, play_animation)
x = 10
y = 10
top = tkinter.Tk()
top.geometry('600x600')
top.title('动画效果')
top.resizable(False, False)
top.wm_attributes('-topmost', 1)
canvas = tkinter.Canvas(top, width=600, height=600, bd=0, highlightthickness=0)
canvas.create_rectangle(0, 0, 600, 600, fill='#beee99')
oval = canvas.create_oval(10, 10, 60, 60, fill='yellow')
canvas.pack()
top.update()
play_animation()
tkinter.mainloop()
运行结果:
eg.五角星
from tkinter import *
import math as m
root = Tk()
w = Canvas(root,width=200,height=100,background='red')
w.pack()
center_x = 100
center_y = 50
r = 50
points = [
# 左上点
center_x - int(r*m.sin(2*m.pi/5)),
center_y - int(r*m.cos(2*m.pi/5)),
# 右上角
center_x + int(r*m.sin(2*m.pi/5)),
center_y - int(r*m.cos(2*m.pi/5)),
# 左下点
center_x - int(r*m.sin(m.pi/5)),
center_y + int(r*m.cos(m.pi/5)),
# 顶点
center_x,
center_y - r,
# 右下点
center_x + int(r*m.sin(m.pi/5)),
center_y + int(r*m.cos(m.pi/5)),
]
w.create_polygon(points,outline='yellow',fill='red')
mainloop()
自制画板
from tkinter import *
root = Tk()
w = Canvas(root,width=400,height=200)
w.pack()
def paint(event):
x1,y1 = (event.x-0.5),(event.y-0.5)
x2, y2 = (event.x + 0.5), (event.y + 0.5)
w.create_oval(x1,y1,x2,y2,fill='red')
w.bind('<B1-Motion>',paint)
Label(root,text='使用鼠标绘制图案').pack(side=BOTTOM)
mainloop()
菜单设计加右键菜单
from tkinter import *
root = Tk()
def callback():
print('点击完成')
menubar = Menu(root)
openVar = IntVar()
saveVar = IntVar()
quitVar = IntVar()
# tearoff这个菜单选项中的设置,它的值只有0和1,将tearoff设置为1以后,
# 就是表明这个菜单是可以独立出来的,如果是0的话就不可以独立出来。
filemenu = Menu(menubar,tearoff=False)
filemenu.add_checkbutton(label = '打开',command=callback,variable=openVar)
filemenu.add_checkbutton(label = '保存',command=callback,variable=saveVar)
# 分隔符
filemenu.add_separator()
filemenu.add_checkbutton(label='退出',command=root.quit,variable=quitVar)
menubar.add_cascade(label='文件',menu=filemenu)
editVar = IntVar()
editmenu = Menu(menubar,tearoff=False)
editmenu.add_radiobutton(label = '剪切',command=callback,variable=editVar,value=1)
editmenu.add_radiobutton(label = '拷贝',command=callback,variable=editVar,value=2)
editmenu.add_radiobutton(label='粘贴',command=callback,variable=editVar,value=3)
menubar.add_cascade(label='编辑',menu=editmenu)
root.config(menu=menubar)
def popup(event):
menubar.post(event.x_root,event.y_root)
root.bind('<Button-3>',popup)
mainloop()
下拉菜单
from tkinter import *
root = Tk()
variable = StringVar()
variable.set('one')
w = OptionMenu(root,variable,'one','two','three')
w.pack()
mainloop()
from tkinter import *
root = Tk()
OPTIONS = [
'red',
'green',
'blue',
'black',
'yellow'
]
variable = StringVar()
variable.set(OPTIONS[0])
w = OptionMenu(root,variable,*OPTIONS)
w.pack()
mainloop()
事件绑定
from tkinter import *
root = Tk()
def callback1(event):
print('点击位置:',event.x,event.y)
def callback2(event):
print('当前位置:',event.x,event.y)
def callback3(event):
print(event.char)
frame = Frame(root,width=200,height=200)
frame.bind('<Button-1>',callback1)
frame.bind('<Motion>',callback2)
frame.bind('<Key>',callback3)
frame.focus_set()
frame.pack()
mainloop()
消息和固值选取
from tkinter import *
root = Tk()
# 消息
w1 = Message(root,text = 'Message',width=100)
w1.pack()
# 固值选取
w2 = Spinbox(root,from_=0,to=10)
w2.pack()
w3 = Spinbox(root,values=('red','yellow','blue'))
w3.pack()
mainloop()
窗格组件
# 显示手柄和分割线
from tkinter import *
m1 = PanedWindow(showhandle=True, sashrelief=SUNKEN) # 默认是左右分布的
m1.pack(fill=BOTH, expand=1)
left = Label(m1, text='left pane')
m1.add(left)
m2 = PanedWindow(orient=VERTICAL, showhandle=True, sashrelief=SUNKEN)
m1.add(m2)
top = Label(m2, text='top pane')
m2.add(top)
bottom = Label(m2, text='bottom pane')
m2.add(bottom)
mainloop()
# 分割线上的类似正方形的东西就是handle
创建顶级窗口
from tkinter import *
root = Tk()
def create():
top = Toplevel()
top.attributes('-alpha',0.5)
top.title('www')
msg = Message(top,text='www.baidu.com')
msg.pack()
Button(root,text='创建顶级窗口',command=create).pack()
mainloop()
网格(Grid)
from tkinter import *
root = Tk()
listbox = Listbox(root)
listbox.pack(fill=BOTH,expand=True)
for i in range(10):
listbox.insert(END,str(i))
mainloop()
from tkinter import *
root = Tk()
Label(root, text='用户名:').grid(row=0, sticky=W)
Label(root, text='密码:').grid(row=1,sticky=W)
photo = PhotoImage(file='qq.png')
Label(root,image=photo).grid(row=0,column=2,rowspan=2,padx=5,pady=5)
Entry(root).grid(row=0,column=1)
Entry(root,show="*").grid(row=1,column=1)
Button(text='提交',width=10).grid(row=2,columnspan=3,pady=5)
mainloop()