以代码为例,教你如何利用tkinter快速开发一个简易可用的程序界面或者游戏

以代码为例,教你如何利用tkinter快速开发一个简易可用的程序界面或者游戏

首先,什么是tkinter?Tkinter模块是Python的标准Tk GUI工具包的接口,是python自带的GUI库。其他更多的内容网上有大量资料,这里不再累述。先贴出简单项目图给你提提兴趣(这些东西在学完后并查阅网上其他资料后是能很简单的写出来的):在这里插入图片描述
既然你选择了tkinter用于开发程序界面,想必是看中了tkinter简易且方便(不用安装)这一点,相比于pygame之类的库,确实显得简单许多且不用学习太多东西。下面开始讲解一些tkinter开发的技巧,主要分为三大块。

  1. tkinter运行基础
  2. 常用控件的介绍
  3. 事件的使用
tkinter运行基础:

tkinter基础主要就是让你能让tkinter运行起来,明白一个完整的界面需要的操作。

首先,我们通过调用Tk()函数即可创建一个tkinter的根(我们后续的开发就是在这个根上进行的,根窗口有且仅能有一个)。有了这个根后,我们可以通过创建一系列控件,将这个根作为参数传到对应的控件创建函数上,视为绑定。最后通过pack函数,我们能将控件布局在窗口的任意一个角落。而对于每个控件,我们可以通过bind函数将与之相关的事件和函数绑定在一起。这些在事件那里会学到。最后,通过mainloop()函数,我们能让他进行一种响应状态,但是要注意,tkinter不是多线程的,会出现阻塞的情况,要想解决,请查阅网上其他资料,简单的程序基本不会出现阻塞。下面是创建一个简单的窗体的代码:

import tkinter
root = tkinter.Tk()
root.title('title!')
root.geometry('400x300')#窗口大小
root.resizable(0,0)#设置窗口可否拉伸,flase为否
root.mainloop()

顺便介绍一些很可能用到的tkinter根窗口函数:

root.after(1000,funtion)
'''该函数为计时函数,表示经过1000s后执行funtion,通过该函数,利用递归我们可以做出一个每x秒执行一个定时函数'''
root.update()
'''很关键的函数,如果你发现你的界面变化好像跟不上函数,多半是更新晚了,tkinter是每到一个loop才更新界面的,所以在你需要及时回馈数据时,用上它吧'''
root.quit()
root.destroy()
'''一般这两个是配套使用的,效果很简单,就是关闭对应窗口'''
root.protocol("WM_DELETE_WINDOW",func1)
'''将系统事件与func1函数绑定,可以做到关不掉的程序'''
root.withdraw()#
root.deiconify()#

下面控件介绍时,为了节约空间,就略去了tkinter的创建代码,统一以上面的代码作为创建基础,并且控件的布局略去不谈,按默认的来就行(或自行上网查阅资料)。

常用控件介绍
  1. button控件

    #root创建过程略去
    buttons = []
    for button in ['开始游戏','速度设置','退出游戏']:
    	buttons.append(tkinter.Button(root,text=button,height = 3,width = 20))
    for i in range(3):
    	buttons[i].pack(side='top',pady = '10px')    
    root.mainloop()
    

    是不是发现出现了一个400x300的界面,还有三个按钮整整齐齐地放在界面上了?

    buttons的属性主要有:根(也就是要放在哪个东西上),text(文本),height(长),width(宽),command(触发函数,这里为了方便就没加上去了)。很多情况下,如果你是为了创建一组按钮,通过数组的方式可以更快捷而且整齐的创建,减少了排版的需求。

  2. label

    #root创建过程略去
    labels = []
    for textx in ['开始游戏','卡组设置','退出游戏']:
    	labels.append(tkinter.Label(root,
    		text = textx,    # 标签的文字
    		bg='Purple',	#背景色
    		fg='#00BFFF',                 # 字体色
    		font=('Arial', 11,'bold'),         # 字体和字体大小
    		width=10, height=4,         # 标签相对长宽,应该是以字体为准
    		cursor =  'hand2',			#鼠标形状
    		compound = 'center'			#字的位置
    		))
    for label in labels:
        label.pack(side='top',pady = '5px')
    root.mainloop()
    

    与button不一样的是,label没有command这一属性。主要用作标签作用。但是,事实上label也可以通过bind函数绑定事件,达到和button一样的效果,这是后话。这两控件其实都差不了太多,看开发情况做选择,一般都是直接用button更方便。

  3. toplevel

    这时候你可能会想了,很多时候你要多窗口开发,只有根窗口这一个窗口怎么够?当然,tkinter提供了一种toplevel组件助你一臂之力。

    #root创建过程略去
    test = tkinter.Toplevel()
    test.title('Duel !')
    test.geometry('400x300')
    test.resizable(0,0)
    root.mainloop()
    

    你会发现此时有两个窗口。

  4. menu

    #root创建过程略去
    menubar = tkinter.Menu(root)
    filemenu = tkinter.Menu(menubar,tearoff=0)
    menubar.add_cascade(label='File', menu=filemenu)
    filemenu.add_command(label='New')#正常使用时,这里肯定会加入参数command
    filemenu.add_command(label='Open')
    filemenu.add_command(label='Save')
    root.config(menu=menubar)
    root.mainloop()
    

    并不是所有程序都需要菜单栏的,但是主要创建方法还是列出来了。对于加入菜单中的功 能,add_command()还有一个参数是command可以绑定与之对应的函数来实现按键功能。

  5. canvas

    这个canvas是我要讲的重中之重,其包含的一系列功能实在太好用了,特别是在开发简单的小游戏上,canvas本身是一个画布,这意味这你可以在上面“画”一切你想画的东西。这主要是由于tkinter所有控件本身都可以布局在其他控件上,这就给我们提供了很大的便利。首先是创建。

    #root创建过程略去
    canvas = tkinter.Canvas(root,
    	width = 200,      # 指定Canvas组件的宽度  
    	height = 150,      # 指定Canvas组件的高度  
    	bg = 'blue')      # 指定Canvas组件的背景色  
    canvas.place(x=0, y=0, relwidth=1, relheight=1)
    root.mainloop()
    
    '''canvas.place_forget(),这是撤掉画布'''
    

    canvas有多种功能,包括画图,移动元素,还有导入图片等等功能,作为一个控件,还能与很多事件绑定在一起。包括且不局限下面的代码实例:

    canvas.create_line((3,3),(3,297),fill='black',width=3)#匿名画一条线
    button_return = tkinter.Button(canvas,text="返回菜单",height = 2,width = 12,command = ?)#实名创建一个按钮在canvas上,command指向一个函数
    text_p = canvas.create_text((350,100),text = "point : "+str(point),fill = "black",font =('Arial', 12))#创建一个文本
    food = canvas.create_image(100,100,image = cardimg)#在100,100的位置创建一个变量名为food的图片cardimg
    

    除开上面列举的功能,还有更多功能,更厉害的是,canvas能对以及创建好的元素进行操作。

    canvas.delete(food)#删除命为food的元素
    canvas.itemconfig(food,image = xxx)#将food元素重新指向别的图片
    canvas.itemconfig(text_p,text = "point : "+str(point))#将text_p文本的内容进行修改
    canvas.bind_all("<KeyPress>",fun)#将canvas的按键事件与fun函数绑定
    

    还有许多操作,这里不再列举。单靠上面的这些操作,我们实际上已经可以做出各类小游戏了,比如扫雷。想必你也知道该怎么搞吧,创建一个canvas,往上面对应坐标创建一堆按钮,每当点到对应按钮,通过绑定的函数执行相应的操作,由于是在canvas上,你还可以随时删了这个按钮然后新增别的图标上去,当然,随你创作。

事件的使用

​ 首先是事件的绑定,可以通过调用bind函数将控件与函数相互绑定,或者直接利用command参数来将函数与控件相互绑定。举一个例子:

import tkinter
root = tkinter.Tk()
root.title('title!')
root.geometry('400x300')#窗口大小
root.resizable(0,0)#设置窗口可否拉伸,flase为否
def handlerAdaptor(fun, **kwds):
	'''事件处理函数的适配器,相当于中介'''
	return lambda fun=fun,kwds=kwds: fun( **kwds) 
def button_hit(a,b,c):
    print(a,b,c)  
button = tkinter.Button(root,text="test",height = 3,width = 20,command = handlerAdaptor(button_hit,a=1,b=2,c=3))
button.pack(side='top',pady = '10px')
root.mainloop()

​ 正常情况下,command指令是无法搞入参数的,我们可以通过万能lambda实现这一功能。

import tkinter
root = tkinter.Tk()
root.title('title!')
root.geometry('400x300')#窗口大小
root.resizable(0,0)#设置窗口可否拉伸,flase为否
def handlerAdaptor(fun, **kwds):
	'''事件处理函数的适配器,相当于中介'''
	return lambda event,fun=fun,kwds=kwds: fun( **kwds) 
def button_hit(a,b,c):
    print(a) 
button = tkinter.Button(root,text="test",height = 3,width = 20)
button.bind("<Enter>",handlerAdaptor(button_hit,a=3,b=2,c=1))
button.pack(side='top',pady = '10px')
root.mainloop()

类似的代码,但是采用的是bind函数,需要注意的是,适配器也发生了一点改变!!!!

bind函数可以绑定大量事件,键盘按键,鼠标位置等等,下面列举一些常见的:

  1. 鼠标刚移到控件上触发
  2. 鼠标离开控件后触发
  3. 鼠标由按下变为释放触发
  4. 传入事件的event.x,event.y分别代表指针位置的x,y坐标
  5. 。。。。。。很多事件和属性网上一查就到,感觉我没必要废话

通过事件将控件与带参数的函数绑定在一起,我们可以实现大量功能。加上canvas强大的功能,我们完全可以通过canvas创建一大堆控件,以及一些图片,图形等,再通过各类事件(如点击,移动)来控制这些控件。这为我们创作简单的2d游戏提供了非常大的便利。

由于是第一篇博文,也不知道重点在哪,可能有错误,排版也有点乱,仅是提供参考讨论,也可以参考我的github代码小游戏项目(开局的图)进行相关的学习(链接:https://github.com/a132980awp/python/tree/master/snack),希望能提供到帮助,有什么疑问可以在评论区提出。

发布了23 篇原创文章 · 获赞 0 · 访问量 580

猜你喜欢

转载自blog.csdn.net/CSDN_Yong/article/details/102634083