简单的学习了Tkinter模块后,今天突然想使用Tkinter来创建一个登陆注册的界面,同时顺便把前几天写的弹球游戏放上去... ... 嗯! (ˇˍˇ) 怎么感觉有点奇怪喃,不管那么多了!另外关于登录和注册的具体实现过程我就没有去做了,毕竟只是做一个初级的演示和记录,当然你可以结合数据库来做甚至可以用文件读写的方式来实现验证登录和注册。
涉及的组件有:菜单、画布、标签、按钮、单行文本
实现的功能有:菜单中的退出、游戏以及Tkinter官方文档链接。按钮中的注册(切换到注册界面)和取消
环境:
系统:win7 64位(Linux下窗口效果略微不同)
工具:Python2.7(64位) +Pycharm
模块:Tkinter(内置)+PIL(与Python3.x中tkinter有差异)
1.效果
2.代码
三个py文件:Main.py(菜单、画布和背景)、Button_label.py(按钮、标签、单行文本框)、Bat_ball.py(附加的游戏)
Main.py
# -*- coding: UTF-8 -*-
from Tkinter import *
from Button_label import *
from PIL import ImageTk
import Bat_ball
import webbrowser
#创建主窗口对象,并定义大小(固定)和位置,添加窗口icon
wind = Tk()
title = "XXX登录XX"
wind.title(title.center(72,' '))
wind.geometry("500x240+400+240")
wind.resizable(0,0)
wind.iconbitmap('login.ico')
#创建菜单容器
menubar = Menu(wind)
wind.config(menu = menubar)
#实例化菜单1,创建下拉菜单,调用add_separate创建分割线
menu1 = Menu(menubar,tearoff = 0)
menubar.add_cascade(label = "编辑",menu = menu1)
menu1.add_command(label = "未使用")
menu1.add_separator()
menu1.add_command(label = "退出",command = wind.quit)
#创建菜单2,分别添加图片(24xp)
# 下拉菜单弹球游戏使用command执行函数调用函数
menu2 = Menu(menubar,tearoff = 0)
menubar.add_cascade(label = "更多",menu = menu2)
imgGame = ImageTk.PhotoImage(file="game.png")
menu2.add_command(label = "弹球游戏",image = imgGame ,compound= "left",command = lambda :Bat_ball.gamerun())
#Tkinter菜单打开网页
imgHelp = ImageTk.PhotoImage(file="help.png")
menu2.add_command(label = "Tkinter",image = imgHelp,compound = "left",command =
lambda:webbrowser.open("http://effbot.org/tkinterbook/tkinter-index.htm"))
#创建画布并将背景图添加到画布上,使用place布局格式(绝对坐标,单位像素)
photo = PhotoImage(file = "main_bg.gif")
canvas = Canvas(wind,width = 500,height = 240)
canvas.create_image(250,120,anchor =CENTER,image = photo)
canvas.place(x= 0,y=0)
#调用主界面控件函数
mainBL(canvas,wind)
#主循环
wind.mainloop()
Button_label.py
# -*- coding: UTF-8 -*-
from Tkinter import *
#主界面组件函数
def mainBL(canvas,wind):
#创建登录标签与单行文本
label_login = Label(wind, text="Name:", anchor="center", bg="white")
label_login.place(x=20, y=20, width=50, height=24, anchor="nw")
text_name = Entry(wind)
text_name.place(x=70, y=20, width=120)
#创建密码标签与单行文本
label_pass = Label(wind, text="Password:", anchor="center", bg="white")
label_pass.place(x=280, y=20, width=80, height=24, anchor="nw")
text_pass = Entry(wind,show = "*")
text_pass.place(x=360, y=20, width=120)
#创建登录按钮
button_login = Button(wind,text = "登录",anchor = "center",activebackground="red",bg = "white",
relief="flat")
button_login.place(x = 100,y=80,width = 60)
#创建注册按钮,点击执行redraw函数
button_registry = Button(wind,text = "注册",anchor = "center",activebackground="red",bg = "white",
relief="flat",command=lambda :redraw())
button_registry.place(x = 230,y=80,width = 60)
#取消按钮,清除文本框输入内容
button_cancel = Button(wind,text = "取消",anchor = "center",activebackground="red" ,bg = "white",
relief="flat" ,command = lambda:(text_name.delete(0,END),text_pass.delete(0,END)))
button_cancel.place(x = 350,y=80,width = 60)
#销毁主界面控件
def redraw():
label_login.destroy()
text_name.destroy()
label_pass.destroy()
text_pass.destroy()
button_login.destroy()
button_registry.destroy()
button_cancel.destroy()
#销毁过后调用注册界面组件函数
registryDetop(canvas,wind)
#注册界面组件函数
def registryDetop(canvas,wind):
reName_name = canvas.create_text(180,30,text="昵称:",font = "叶根友毛笔行书2.0版 15 bold",fill="white")
reName_text = Entry(wind)
reName_text.place(x = 210,y = 20,width =150)
rePass_name = canvas.create_text(180,80,text="密码:",font = "叶根友毛笔行书2.0版 15 bold",fill="orange")
rePass_text = Entry(wind)
rePass_text.place(x = 210,y = 70,width =150)
reMail_name = canvas.create_text(180,130,text="邮箱:",font = "叶根友毛笔行书2.0版 15 bold",fill="green")
reMail_text = Entry(wind)
reMail_text.place(x = 210,y = 120,width =150)
reButton = Button(wind,text = "确定",bg ="white")
reButton.place(x = 170,y = 170)
canButton = Button(wind,text = "取消",bg ="white",command =lambda:
(reName_text.delete(0,END),rePass_text.delete(0,END),reMail_text.delete(0,END)))
canButton.place(x = 290,y = 170)
Bat_ball.py
# -*- coding: UTF-8 -*-
from Tkinter import *
import random
import time
def gamerun():
#定义主窗口
windgame = Tk()
windgame.geometry("700x600+100+00")
windgame.title("弹球游戏")
windgame.resizable(0,0)
#创建画布和记分牌(并刷新显示)
canvasgame = Canvas(windgame, width = 700,height = 600,bg= "aliceblue")
coreid=canvasgame.create_text(600,0,text = "记分牌\n分数:0",font = ('Cambria',10),anchor = "n",justify = "center")
canvasgame.pack()
windgame.update()
#随机取小球初始化位置
positions = (20,50,80,130,180,200,230,280,300,350)
positionx = random.choice (positions)
positiony = random.choice (positions)
#随机颜色列表
color_pool = ("red","green","orange","grey","white","blue",
"Pink","Orchid","Purple","SkyBlue","YellowGreen")
#定义球类(碰撞时球运动改变,内设碰撞处理函数)
class Ball:
def __init__(self,coords,colors):
self.coords = coords
self.color = colors
self.id = canvasgame.create_oval(coords,fill= colors)
self.wid= canvasgame.winfo_width()
self.height = canvasgame.winfo_height()
self.speedx = random.choice((-3,3))
self.speedy = random.choice((-3,3))
self.move = canvasgame.move(self.id,positionx,positiony)
self.turn = 0
self.core = 0
#碰撞处理函数(通过传入全局球拍坐标),主要用来做控制
def draw(self,batpos):
canvasgame.move(self.id,self.speedx,self.speedy)
ballpos = canvasgame.coords(self.id)
#小球碰壁换向(碰下板计分为-200)
if ballpos[0] < 0:
self.speedx = 3
elif ballpos[1] < 0:
self.speedy = 3
self.turn = 0
elif ballpos[2] > self.wid:
self.speedx = -3
elif ballpos[3] > self.height:
self.speedy = -3
self.turn =1
self.core = self.core - 200
canvasgame.itemconfig(coreid, text=("记分牌\n分数:%d" %self.core))
#小球碰板换向并计分(碰上板为正计400并随机换色,碰下板为-400不换色)
if ballpos[2] > batpos[0] and ballpos[0] < batpos[2] and ballpos[3] > batpos[1]:
#碰上板
if ballpos[3] >= batpos[1] and self.turn ==0:
if ballpos[3] <= (batpos[1] + 3):
self.speedy = -3
self.core=self.core + 400
canvasgame.itemconfig(coreid, text=("记分牌\n分数:%d" %self.core))
canvasgame.itemconfig(self.id, fill=random.choice(color_pool))
#碰下板
if ballpos[1] <= batpos[3] and self.turn ==1:
if ballpos[1] >= (batpos[3] - 3):
self.speedy = 3
self.core = self.core - 400
canvasgame.itemconfig(coreid, text=("记分牌\n分数:%d" %self.core))
return self.core
#定义球拍类
class Bat:
def __init__(self,coords,colors):
self.coords = coords
self.colors = colors
self.id = canvasgame.create_rectangle(coords,fill = self.colors)
self.width = canvasgame.winfo_width()
canvasgame.move(self.id,(700-self.coords[2])/2,400)
#键盘监听处理函数
def batbind(self,event):
if event.keysym == "Left":
canvasgame.move(self.id,self.Lspeed,0)
if event.keysym == "Right":
canvasgame.move(self.id,self.Rspeed,0)
#板的移动函数(并监听键盘控制键)
def draw(self):
self.Rspeed = 10
self.Lspeed = -10
global pos
pos = canvasgame.coords(self.id)
if pos[0] <= 0:
self.Lspeed = 0
elif pos[2] >= self.width:
self.Rspeed = 0
canvasgame.bind_all("<KeyPress-Left>",self.batbind)
canvasgame.bind_all("<KeyPress-Right>",self.batbind)
#定义球和板大小并为球和球拍创建实例
ballcoord = 20,20,46,46
batcoord = 0,0,150,4
bat = Bat(batcoord,"blue")
ball = Ball(ballcoord,"red")
#结束游戏界面
def endWindow():
canvasgame.delete(ball.id, bat.id)
canvasover = canvasgame.create_text(350,300,text="o(╥﹏╥)o\n爱的太早,结束的太快!",
font=('Cambria', 20), justify="center")
#主循环,调用球和球拍,间断刷新(小于-1000分结束)
while True:
bat.draw()
endCore=ball.draw(pos)
if endCore <= -1000:
endWindow()
break
windgame.update()
time.sleep(0.01)
windgame.mainloop()
3.文件
除了三个.py文件,还有窗口图标、菜单和背景图片,如有需要下面有打包