闲来无事,用python制作了一个可以在七夕/情人节送对象的礼物,展示一把程序员的浪漫~
男朋友的同门看到了之后表示,你女朋友好牛逼&浪漫
那么话不多说,我们这就开始吧!
1. 库函数包装
使用的语言是python,用到的库函数包含tkinter,turtle和PIL,其中只有PIL需要下载,其他都是python自带的,下载代码:
pip install pillow
2. 创建tkinter基本窗口
basedesk
相当于桌子,之后创建的tk.Frame
相当于桌布,多张桌布可以在桌子上切换。
class basedesk():
def __init__(self, master):
self.root = master
self.root.config()
self.root.title('开启我们的故事')
self.root.geometry('600x450')
self.root.resizable(False, False)
Init(self.root)
3. 封面页
我设计的封面页只包含文字和一个切换按钮,分别使用tkinter自带的Label和Button:
tk.Label(self.face, text=text, font=title).pack()
tk.Button(self.face, text="开启我们的故事", font=font, command=self.next, bg=color).pack()
完整的一页:
from turtle import *
import tkinter as tk
from PIL import Image, ImageTk
font=("华文行楷", 17, "normal") # 正文格式
title=("华文行楷", 30, "normal") # 标题格式
color = 'pink'
class Init():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n\n\n准备好开启我们的故事了吗\n\n'
tk.Label(self.face, text=text, font=title).pack()
tk.Button(self.face, text="开启我们的故事", font=font, command=self.next, bg=color).pack()
def next(self):
self.face.destroy()
StoryBegin(self.master)
效果展示:
4. 正文页
我设计的正文页包含文字和图片和一个切换按钮,图片采用函数showImg
导入。参数:
-
face
表示要显示的Frame -
name
表示图片的名字,这里采用的格式是png,可以自己修改。 -
side
表示图片的排列方式,包含TOP,BOTTOM,LEFT和RIGHT四种 -
rate
表示图片的缩放倍数
def showImg(face, name, side=tk.TOP, rate=1.0):
global render
load = Image.open('{}.png'.format(name))
size = (int(load.size[0]*rate), int(load.size[1]*rate))
load = load.resize(size)
render[name] = ImageTk.PhotoImage(load)
img = tk.Label(face, image=render[name]).pack(side=side)
完整的一页:
class StoryBegin():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n2018年9月10日\n我们的故事开始\n'\
'还记得我们发的官宣说说吗?\n'\
'还是一起跑完步随手拍的自拍'
tk.Label(self.face, text=text, font=font).pack()
tk.Button(self.face, text="继续我们的故事", command=self.next, bg=color).pack(side=tk.BOTTOM)
showImg(self.face, 'couple', rate=1.5)
def next(self):
self.face.destroy()
Milktea(self.master)
效果展示:
4. 测试页1
单纯的叙述多没意思呀,来增加一点难度吧。可以增加一点情侣之间的小秘密提问哦~
可以用Label输入问题,Entry插入文本框,用来输入答案,Button用来确认输入
text = '\n随堂小测验开始~\n'\
'还记得你第一次请我喝的奶茶是什么口味吗?'
tk.Label(self.face, text=text, font=font).pack()
self.namestr = tk.StringVar()
tk.Entry(self.face, textvariable=self.namestr, font=font).pack(side=tk.TOP)
tk.Button(self.face, text="确定", command=self.judge, bg=color).pack(side=tk.TOP)
用一个judge函数判断答案正误:
def judge(self):
if self.namestr.get() != '草莓':
tk.messagebox.askokcancel(title='警告', message='回答错误!\n提示:输入两个字哦~')
else:
self.story_continue()
错误的话利用messagebox
弹出提示窗口:
正确的话出现后续故事,和正文一致,不再赘述:
完整的一页:
class Milktea():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n随堂小测验开始~\n'\
'还记得你第一次请我喝的奶茶是什么口味吗?'
tk.Label(self.face, text=text, font=font).pack()
self.namestr = tk.StringVar()
tk.Entry(self.face, textvariable=self.namestr, font=font).pack(side=tk.TOP)
tk.Button(self.face, text="确定", command=self.judge, bg=color).pack(side=tk.TOP)
def judge(self):
if self.namestr.get() != '草莓':
tk.messagebox.askokcancel(title='警告', message='回答错误!\n提示:输入两个字哦~')
else:
self.story_continue()
def story_continue(self):
text = '\n回答正确~\n'\
'可不要小瞧这一杯奶茶哟\n'\
'第一次的时候我告诉你喜欢草莓味\n'\
'然后你就记住了,并且第二次直接买到了我喜欢的口味\n'\
'当时就觉得,嗯,这个男银,不戳\n'
tk.Label(self.face, text=text, font=font).pack()
tk.Button(self.face, text="继续我们的故事", command=self.next, bg=color).pack(side=tk.TOP)
def next(self):
self.face.destroy()
Study(self.master)
5. 测试页2
如果想要在测试页插入图片导致内容放不下,也可以将答案放到第二页。
第一页:
如果回答错误:
如果回答正确,进入第2页:
完整的两页的代码:
class Christmas():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n根据图片,你能看出这是哪一天吗?'
tk.Label(self.face, text=text, font=font).pack()
self.namestr = tk.StringVar()
tk.Entry(self.face, textvariable=self.namestr, font=font).pack(side=tk.TOP)
tk.Button(self.face, text="确定", command=self.judge, bg=color).pack(side=tk.TOP)
showImg(self.face,'couple', rate=1.5)
def judge(self):
if self.namestr.get() != '2018年12月25日':
tk.messagebox.askokcancel(title='警告', message='回答错误!\n提示:输入格式:XXXX年XX月XX日~')
else:
self.next()
def next(self):
self.face.destroy()
Christmas2(self.master)
class Christmas2():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n回答正确~\n是2018年12月25日\n'\
'当然是我们在一起的第一个圣诞节啦!'
tk.Label(self.face, text=text, font=font).pack()
showImg(self.face,'couple', rate=1.5)
text = '我们还盖了手印,\n'\
'要在一起一辈子不分开哟'
tk.Label(self.face, text=text, font=font).pack()
b = tk.Button(self.face, text="继续我们的故事", bg=color, command=self.next).pack(side=tk.BOTTOM)
def next(self):
self.face.destroy()
Heart(self.master)
6. 结尾页
交替正文页和测试页,就可以组成你们的专属小故事啦~
在故事的最后,也要给闯关成功的TA一点小奖励呢。
让我们用turtle库函数画个比心小人和一段真情的表白吧
实际上的小人是会动的哦,别看这张图看起来简单,它的代码可不短~
完整一页代码:
class Heart():
def __init__(self, master):
self.master = master
self.master.config()
self.canvas = tk.Canvas(self.master, width=600, height=450)
self.canvas.pack()
self.tu = RawTurtle(self.canvas)
self.tu.hideturtle()
self.tu.home()
self.tu.clear()
self.tu.speed(0)
self.tu.screen.delay(0)
self.person(0, 50)
s = '亲爱的宝贝:\n'\
' 今天不是什么特别的日子,\n'\
' 没有什么日子需要赋予特殊意义,\n'\
' 因为我时时爱你,\n'\
' 不需要在某个节点才袒露心意。'
self.word(s, -100, -150)
def go_to(self, x, y):
self.tu.penup()
self.tu.goto(x, y)
self.tu.down()
def ring(self, a,b,c,d):
for i in range(a):
self.tu.forward(b)
if d == 'right':
self.tu.right(c)
else:
self.tu.left(c)
def heart(self, x, y, size):
self.go_to(x, y)
self.tu.left(150)
self.tu.begin_fill()
self.tu.forward(51*size)
self.ring(150,size,0.3,'right')
self.ring(210,size,0.786,'right')
self.tu.left(120)
self.ring(210,size,0.786,'right')
self.ring(150,size,0.3,'right')
self.tu.forward(51*size)
self.tu.end_fill()
def person(self, xbias, ybias):
#头部
self.tu.color('black')
self.go_to(-228, 72-ybias)
self.tu.pensize(3)
self.tu.left(150)
self.ring(350,1,0.8,'right')
#手臂
self.tu.left(150)
self.tu.forward(70)
self.tu.left(90)
self.tu.forward(10)
self.ring(200,0.1,0.9,'right')
self.tu.forward(10)
self.tu.left(90)
self.tu.forward(20)
self.ring(200,0.1,0.9,'right')
self.tu.forward(10)
self.tu.left(90)
self.ring(200,0.2,0.9,'right')
self.tu.left(100)
self.tu.left
self.tu.forward(80)
#身体
self.go_to(-228, 72-ybias)
self.tu.left(40)
self.tu.forward(40)
self.ring(120,0.2,0.9,'left')
self.go_to(-219,52-ybias)
self.tu.right(95)
self.tu.forward(80)
self.tu.right(85)
self.ring(205,0.1,0.9,'left')
self.tu.forward(40)
self.tu.left(90)
self.tu.forward(10)
self.ring(200,0.1,0.9,'right')
self.tu.forward(10)
self.tu.left(90)
self.tu.forward(40)
self.ring(205,0.1,0.9,'left')
self.tu.right(92)
self.tu.forward(90)
#左眼
self.go_to(-217,155-ybias)
self.tu.fillcolor('black')
self.tu.begin_fill()
self.tu.circle(5)
self.tu.end_fill()
#右眼
self.go_to(-169,158-ybias)
self.tu.fillcolor('black')
self.tu.begin_fill()
self.tu.circle(5)
self.tu.end_fill()
#微笑
self.go_to(-210,132-ybias)
self.tu.right(180)
self.ring(200,0.2,0.9,'left')
#腮红
self.tu.color('#ffa0a0')
self.tu.pensize(5)
self.tu.left(170)
self.go_to(-235, 135-ybias)
self.tu.forward(11)
self.go_to(-225, 135-ybias)
self.tu.forward(11)
self.go_to(-155, 140-ybias)
self.tu.forward(11)
self.go_to(-165, 140-ybias)
self.tu.forward(11)
#比心
self.tu.setheading(0)
self.heart(-35, 135-ybias, 0.10)
self.tu.setheading(0)
self.heart(5, 150-ybias, 0.13)
self.tu.setheading(0)
self.heart(52, 165-ybias, 0.15)
def word(self, s, x, y):
self.go_to(x, y)
self.tu.write(s, align="left", font=("华文行楷", 20, "normal"))
下面是全部的完整代码。
# -*- coding: utf-8 -*-
from turtle import *
import tkinter as tk
from PIL import Image, ImageTk
font=("华文行楷", 17, "normal") # 正文格式
title=("华文行楷", 30, "normal") # 标题格式
render = {}
color = 'pink'
# 载入图片
def showImg(face, name, side=tk.TOP, rate=1.0):
global render
load = Image.open('{}.png'.format(name))
size = (int(load.size[0]*rate), int(load.size[1]*rate))
load = load.resize(size)
render[name] = ImageTk.PhotoImage(load)
img = tk.Label(face, image=render[name]).pack(side=side)
# 桌面
class basedesk():
def __init__(self, master):
self.root = master
self.root.config()
self.root.title('开启我们的故事')
self.root.geometry('600x450')
self.root.resizable(False, False)
Init(self.root)
# 开始页
class Init():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n\n\n准备好开启我们的故事了吗\n\n'
tk.Label(self.face, text=text, font=title).pack()
tk.Button(self.face, text="开启我们的故事", font=font, command=self.next, bg=color).pack()
def next(self):
self.face.destroy()
StoryBegin(self.master)
# 正文页
class StoryBegin():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n2018年9月10日\n我们的故事开始\n'\
'还记得我们发的官宣说说吗?\n'\
'还是一起跑完步随手拍的自拍'
tk.Label(self.face, text=text, font=font).pack()
tk.Button(self.face, text="继续我们的故事", command=self.next, bg=color).pack(side=tk.BOTTOM)
showImg(self.face, 'couple', rate=1.5)
def next(self):
self.face.destroy()
Milktea(self.master)
# 测试页1
class Milktea():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n随堂小测验开始~\n'\
'还记得你第一次请我喝的奶茶是什么口味吗?'
tk.Label(self.face, text=text, font=font).pack()
self.namestr = tk.StringVar()
tk.Entry(self.face, textvariable=self.namestr, font=font).pack(side=tk.TOP)
tk.Button(self.face, text="确定", command=self.judge, bg=color).pack(side=tk.TOP)
def judge(self):
if self.namestr.get() != '草莓':
tk.messagebox.askokcancel(title='警告', message='回答错误!\n提示:输入两个字哦~')
else:
self.story_continue()
def story_continue(self):
text = '\n回答正确~\n'\
'可不要小瞧这一杯奶茶哟\n'\
'第一次的时候我告诉你喜欢草莓味\n'\
'然后你就记住了,并且第二次直接买到了我喜欢的口味\n'\
'当时就觉得,嗯,这个男银,不戳\n'
tk.Label(self.face, text=text, font=font).pack()
tk.Button(self.face, text="继续我们的故事", command=self.next, bg=color).pack(side=tk.TOP)
def next(self):
self.face.destroy()
Christmas(master)(self.master)
# 测试页2-1
class Christmas():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n根据图片,你能看出这是哪一天吗?'
tk.Label(self.face, text=text, font=font).pack()
self.namestr = tk.StringVar()
tk.Entry(self.face, textvariable=self.namestr, font=font).pack(side=tk.TOP)
tk.Button(self.face, text="确定", command=self.judge, bg=color).pack(side=tk.TOP)
showImg(self.face,'couple', rate=1.5)
def judge(self):
if self.namestr.get() != '2018年12月25日':
tk.messagebox.askokcancel(title='警告', message='回答错误!\n提示:输入格式:XXXX年XX月XX日~')
else:
self.next()
def next(self):
self.face.destroy()
Christmas2(self.master)
# 测试页2-2
class Christmas2():
def __init__(self, master):
self.master = master
self.master.config(width=600, height=400)
self.face = tk.Frame(self.master)
self.face.pack()
text = '\n回答正确~\n是2018年12月25日\n'\
'当然是我们在一起的第一个圣诞节啦!'
tk.Label(self.face, text=text, font=font).pack()
showImg(self.face,'couple', rate=1.5)
text = '我们还盖了手印,\n'\
'要在一起一辈子不分开哟'
tk.Label(self.face, text=text, font=font).pack()
b = tk.Button(self.face, text="继续我们的故事", bg=color, command=self.next).pack(side=tk.BOTTOM)
def next(self):
self.face.destroy()
Heart(self.master)
# 结尾页
class Heart():
def __init__(self, master):
self.master = master
self.master.config()
self.canvas = tk.Canvas(self.master, width=600, height=450)
self.canvas.pack()
self.tu = RawTurtle(self.canvas)
self.tu.hideturtle()
self.tu.home()
self.tu.clear()
self.tu.speed(0)
self.tu.screen.delay(0)
self.person(0, 50)
s = '亲爱的宝贝:\n'\
' 今天不是什么特别的日子,\n'\
' 没有什么日子需要赋予特殊意义,\n'\
' 因为我时时爱你,\n'\
' 不需要在某个节点才袒露心意。'
self.word(s, -100, -150)
def go_to(self, x, y):
self.tu.penup()
self.tu.goto(x, y)
self.tu.down()
def ring(self, a,b,c,d):
for i in range(a):
self.tu.forward(b)
if d == 'right':
self.tu.right(c)
else:
self.tu.left(c)
def heart(self, x, y, size):
self.go_to(x, y)
self.tu.left(150)
self.tu.begin_fill()
self.tu.forward(51*size)
self.ring(150,size,0.3,'right')
self.ring(210,size,0.786,'right')
self.tu.left(120)
self.ring(210,size,0.786,'right')
self.ring(150,size,0.3,'right')
self.tu.forward(51*size)
self.tu.end_fill()
def person(self, xbias, ybias):
#头部
self.tu.color('black')
self.go_to(-228, 72-ybias)
self.tu.pensize(3)
self.tu.left(150)
self.ring(350,1,0.8,'right')
#手臂
self.tu.left(150)
self.tu.forward(70)
self.tu.left(90)
self.tu.forward(10)
self.ring(200,0.1,0.9,'right')
self.tu.forward(10)
self.tu.left(90)
self.tu.forward(20)
self.ring(200,0.1,0.9,'right')
self.tu.forward(10)
self.tu.left(90)
self.ring(200,0.2,0.9,'right')
self.tu.left(100)
self.tu.left
self.tu.forward(80)
#身体
self.go_to(-228, 72-ybias)
self.tu.left(40)
self.tu.forward(40)
self.ring(120,0.2,0.9,'left')
self.go_to(-219,52-ybias)
self.tu.right(95)
self.tu.forward(80)
self.tu.right(85)
self.ring(205,0.1,0.9,'left')
self.tu.forward(40)
self.tu.left(90)
self.tu.forward(10)
self.ring(200,0.1,0.9,'right')
self.tu.forward(10)
self.tu.left(90)
self.tu.forward(40)
self.ring(205,0.1,0.9,'left')
self.tu.right(92)
self.tu.forward(90)
#左眼
self.go_to(-217,155-ybias)
self.tu.fillcolor('black')
self.tu.begin_fill()
self.tu.circle(5)
self.tu.end_fill()
#右眼
self.go_to(-169,158-ybias)
self.tu.fillcolor('black')
self.tu.begin_fill()
self.tu.circle(5)
self.tu.end_fill()
#微笑
self.go_to(-210,132-ybias)
self.tu.right(180)
self.ring(200,0.2,0.9,'left')
#腮红
self.tu.color('#ffa0a0')
self.tu.pensize(5)
self.tu.left(170)
self.go_to(-235, 135-ybias)
self.tu.forward(11)
self.go_to(-225, 135-ybias)
self.tu.forward(11)
self.go_to(-155, 140-ybias)
self.tu.forward(11)
self.go_to(-165, 140-ybias)
self.tu.forward(11)
#比心
self.tu.setheading(0)
self.heart(-35, 135-ybias, 0.10)
self.tu.setheading(0)
self.heart(5, 150-ybias, 0.13)
self.tu.setheading(0)
self.heart(52, 165-ybias, 0.15)
def word(self, s, x, y):
self.go_to(x, y)
self.tu.write(s, align="left", font=("华文行楷", 20, "normal"))
if __name__ == '__main__':
root = tk.Tk()
basedesk(root)
root.mainloop()