python-tkinter学习实例
在好友的邀请下,尝试用tkinter做一个卡牌的普通界面显示,正好练习下python的写法。
花了两天学习,写了两天代码,做了个最基本的demo。显示如下:
其中需要引入的第三方库主要有,PIL、PILLOW,其它的都是直接引入即可。
1.1、这里贴下下载地址,以WINDOWS系统为例:
PILwin32:http://files.cnblogs.com/files/pcat/PILwin32.zip
PILwin64:http://files.cnblogs.com/files/pcat/PILwin64.zip
1.2、windows安装Pillow
pip install Pillow
或者在http://www.lfd.uci.edu/~gohlke/pythonlibs/#pillow 下载wheel文件使用pip安装
程序中用到的图片主要有:
需要图片资源的小伙伴可以自行上git上下载:
https://github.com/ishikota/PyPokerGUI
pypokergui--server--static
贴上程序的源码,仅供参考:
# -*- coding: utf-8 -*-
from Tkinter import *
from PIL import Image,ImageTk import Image,math,random,time,sched
import threading as thd
class card2:
#定义全局变量
#总牌数
num_list = ['', '', '', '', '', '', '','T', 'J','Q','K', 'A','']
# 全局变量纪录玩家当前要打出的牌数字
#当前牌面字符串
str_num = '';
#当前牌面字符串在num_list中的位置
index_num = -1;
# 中间桌面上牌的大小
mid_num = -2;
#判断是否会生成重复的牌
check_list = [];
#记录当前回合数
round_num = 1;
#当前玩家手中牌位置
cur_position = 0;
#定义玩家当前手中牌的集合
player_card_list = [];
player1_card_list = [];
player2_card_list = [];
player3_card_list = [];
player4_card_list = []; #变量判断玩家身份,默认为玩家
cur_identify = 1; def __init__(self):
self.tk = Tk()
#tk.geometry('1200x1600')
self.tk.title('A Easy Card Game') self.img = Image.open('images/poker_pot.png')
self.w_box = 120
self.h_box = 120
self.w, self.h = self.img.size
# w,h = img2.size
# 缩放图像让它保持比例,同时限制在一个矩形框范围内
self.img_resized = self.resize(self.w, self.h, self.w_box, self.h_box, self.img)
self.photo = ImageTk.PhotoImage(self.img_resized)
# frm_TL = Frame(bg = 'WHITE',width = 300, height = 200)
self.frm_T = Frame(bg='white', width=300, height=200)
self.frm_L = Frame(bg='white', width=300, height=400)
self.frm_M = Frame(bg='white', width=200, height=400)
self.frm_R = Frame(bg='white', width=300, height=400)
self.frm_B = Frame(bg='white', width=400, height=200)
# frm_TL.grid(row=0,column=0)
self.frm_T.grid(row=0, column=1)
self.frm_L.grid(row=1, column=0)
self.frm_M.grid(row=1, column=1)
self.frm_R.grid(row=1, column=2)
self.frm_B.grid(row=2, column=1)
# Top
Label(self.frm_T, text="Player3", font=('Arial', 16)).grid(column=1, sticky=N)
Button(self.frm_T, text="重新发牌", command=self.replay, width=8, height=1,
font=('Arial', 16)).grid(row=0, column=3)
self.frm_T_label_L = Label(self.frm_T, image=self.photo)
self.frm_T_label_L.image = self.photo
self.frm_T_label_L.grid(row=1, column=0, sticky=E)
# frm_T_label_L.grid(row=1,column=1,columnspan=2,rowspan=2,sticky=W+E+N+S,padx=5,pady=5)
self.frm_T_label_M = Label(self.frm_T, image=self.photo)
self.frm_T_label_M.image = self.photo
self.frm_T_label_M.grid(row=1, column=1,padx=10, sticky=E)
self.frm_T_label_R = Label(self.frm_T, image=self.photo)
self.frm_T_label_R.image = self.photo
self.frm_T_label_R.grid(row=1, column=2, sticky=E) # Left
Label(self.frm_L, text="Player4", font=('Arial', 16)).grid(row=1, column=0, sticky=N)
self.frm_L_label_T = Label(self.frm_L, image=self.photo)
self.frm_L_label_T.image = self.photo
self.frm_L_label_T.grid(row=0, column=1, sticky=E)
self.frm_L_label_T = Label(self.frm_L, image=self.photo)
self.frm_L_label_T.image = self.photo
self.frm_L_label_T.grid(row=1, column=1, sticky=E)
self.frm_L_label_T = Label(self.frm_L, image=self.photo)
self.frm_L_label_T.image = self.photo
self.frm_L_label_T.grid(row=2, column=1, sticky=E) # Middle
self.frm_M_label_T = Label(self.frm_M, image=self.photo)
self.frm_M_label_T.image = self.photo
self.frm_M_label_T.grid(row=1, column=0, sticky=E)
self.frm_M_text = Text(self.frm_M, width=30, height=6, bg='Green', font=('Verdana', 15)) #self.frm_M_text.insert('1.0', 'this is '+str(self.round_num)+' round\n')
#self.frm_M_text.insert(END, 'last round')
self.frm_M_text.grid(row=2, column=0, columnspan=2) # Right frm_R
self.frm_R_label_T = Label(self.frm_R, image=self.photo)
self.frm_R_label_T.image = self.photo
self.frm_R_label_T.grid(row=0, column=0, sticky=E)
self.frm_R_label_T = Label(self.frm_R, image=self.photo)
self.frm_R_label_T.image = self.photo
self.frm_R_label_T.grid(row=1, column=0, sticky=E)
self.frm_R_label_T = Label(self.frm_R, image=self.photo)
self.frm_R_label_T.image = self.photo
self.frm_R_label_T.grid(row=2, column=0, sticky=E)
Label(self.frm_R, text="Player2", font=('Arial', 16)).grid(row=1, column=1, sticky=N) # 初始化玩家手中牌
self.load_sys() self.main_start() self.frm_B_label_T_4 = Label(self.frm_B, image=self.photo)
self.frm_B_label_T_4.image = self.photo
self.frm_B_label_T_4.grid(row=0, column=3, sticky=E)
Label(self.frm_B, text="Player1", font=('Arial', 16)).grid(row=1, column=1, sticky=N)
Button(self.frm_B, text="出牌", command=self.discard, width=6, height=1,
font=('Arial', 16)).grid(row=1, column=3)
Button(self.frm_B, text="PASS", command=self.player_pass, width=6, height=1,
font=('Arial', 16)).grid(row=1, column=4) def resize(self,w, h, w_box, h_box, pil_image):
'''''
resize a pil_image object so it will fit into
a box of size w_box times h_box, but retain aspect ratio
对一个pil_image对象进行缩放,让它在一个矩形框内,还能保持比例
''' f1 = 1.0 * w_box / w # 1.0 forces float division in Python2
f2 = 1.0 * h_box / h
factor = min([f1, f2])
# print(f1, f2, factor) # test
# use best down-sizing filter
width = int(w * factor)
height = int(h * factor)
return pil_image.resize((width, height), Image.ANTIALIAS)
def replay(self):
self.load_sys() #初始化玩家手中牌
def load_sys(self):
# 初始化当前玩家手中牌集合,先重置
self.player1_card_list = []
self.player2_card_list = []
self.check_list = []
self.cur_identify = 1
for i in range(3):
num = random.randint(0,12)
#判断是否生成重复的牌,去重
while self.check_list.__contains__(num):
num = random.randint(0, 12)
cur_str = self.num_list[num]
photo_current = ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box, Image.open('images/card_C' + str(cur_str) + '.png')))
frm_B_label_T_1 = Label(self.frm_B, image=photo_current)
frm_B_label_T_1.image = photo_current
frm_B_label_T_1.grid(row=0, column=i,sticky=E)
frm_B_label_T_1.bind('<ButtonRelease-1>', self.handlerAdaptor(self.choose, cur_str,i))
self.check_list.append(num)
self.player1_card_list.append(cur_str)
#生成玩家2手中的牌
num2 = random.randint(0, 12)
# 判断是否生成重复的牌,去重
while self.check_list.__contains__(num2):
num2 = random.randint(0, 12)
cur_str2 = self.num_list[num2]
self.check_list.append(num2)
self.player2_card_list.append(cur_str2) print(self.player1_card_list)
print(self.player2_card_list)
#记录当前轮数并递增
self.frm_M_text.insert('1.0', 'this is ' + str(self.round_num) + ' round\n')
self.round_num+=1 # 清空桌面上的牌
frm_M_label_T = Label(self.frm_M, image=self.photo)
frm_M_label_T.image = self.photo
frm_M_label_T.grid(row=1, column=0, sticky=E)
# 重置玩家手中当前牌
frm_B_label_T_4 = Label(self.frm_B, image=self.photo)
frm_B_label_T_4.image = self.photo
frm_B_label_T_4.grid(row=0, column=3, sticky=E)
#重置桌面上牌的大小
self.mid_num = -2
# Bottom
def choose(self,event,a,position):
self.frm_M_text.insert('1.0','Now Your Card Is C'+str(a)+'\n')
photo_cur = ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box, Image.open('images/card_C' + str(a) + '.png')))
frm_B_label_T_4 = Label(self.frm_B, image=photo_cur)
frm_B_label_T_4.image = photo_cur
frm_B_label_T_4.grid(row=0, column=3, sticky=E)
self.str_num = a
self.cur_position = position
def handlerAdaptor(self,fun, *kwds):
'''''事件处理函数的适配器,相当于中介,此处接收2个参数,那个event是从那里来的呢,我也纳闷,这也许就是python的伟大之处吧'''
return lambda event,fun=fun,kwds=kwds: fun(event, *kwds)
def discard(self):
if self.cur_identify == 1:
if self.str_num != '':
self.index_num = self.num_list.index(self.str_num)
if self.index_num == -1:
self.frm_M_text.insert('1.0','请选择一张牌\n')
#return '请选择一张牌'
#判断要打出的牌与桌面上的牌大小
elif self.index_num <= self.mid_num:
self.frm_M_text.insert('1.0', '请选择一张大牌\n')
# return '请选择一张大牌'
else:
photo_mid = ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box, Image.open('images/card_C' + str(self.str_num) + '.png')))
frm_M_label_T = Label(self.frm_M, image=photo_mid)
frm_M_label_T.image = photo_mid
frm_M_label_T.grid(row=1, column=0, sticky=E)
#清空玩家手中当前牌
frm_B_label_T_4 = Label(self.frm_B, image=self.photo)
frm_B_label_T_4.image = self.photo
frm_B_label_T_4.grid(row=0, column=3, sticky=E)
#frm_B_label_T_4.grid_forget()
#给当前桌面牌赋值
self.mid_num = self.index_num
#重置玩家手中牌
frm_B_label_T_X = Label(self.frm_B, image=self.photo)
frm_B_label_T_X.image = self.photo
frm_B_label_T_X.grid(row=0, column=self.cur_position, sticky=E)
self.frm_M_text.insert('1.0', 'Player1 Play The Card!'+ str(self.str_num) +'\n')
self.player1_card_list.remove(self.str_num)
if self.player1_card_list.__len__() == 0:
self.frm_M_text.insert('1.0', 'Congratulations! Player1 Win The Game!\n')
return
#当玩家打出牌后,切换到电脑2,调用电脑出牌方法
self.cur_identify +=1
self.discard_pc(self.cur_identify)
else:
self.frm_M_text.insert('1.0', '请等待其它玩家出牌\n') #没有可出的牌,切换到下一个对手
def player_pass(self):
# 重置中间牌的大小
self.mid_num = -2
#切换玩家
self.cur_identify += 1
self.discard_pc(self.cur_identify) # def player_pc(self,iden):
# if iden == 2:
# self.player_card_list = self.player2_card_list
#
# if iden ==3:
# self.cur_identify = 1 def discard_pc(self,iden):
card_list_pc = []
if iden == 2:
for i in range(self.player2_card_list.__len__()):
#将当前牌转化成索引号进行比较大小
self.index_pc_num = self.num_list.index(self.player2_card_list[i]) if self.index_pc_num > self.mid_num:
card_list_pc.append(self.player2_card_list[i])
card_list_pc.sort()
if len(card_list_pc) > 0:
self.index_pc_num_temp = self.num_list.index(card_list_pc[0])
self.mid_num = self.index_pc_num_temp
photo_mid = ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box,
Image.open('images/card_C' + str(card_list_pc[0]) + '.png')))
frm_M_label_T = Label(self.frm_M, image=photo_mid)
frm_M_label_T.image = photo_mid
frm_M_label_T.grid(row=1, column=0, sticky=E)
self.frm_M_text.insert('1.0', 'Player2 Play The Card!' + str(card_list_pc[0]) + '\n')
self.player2_card_list.remove(card_list_pc[0]) if self.player2_card_list.__len__() == 0:
self.frm_M_text.insert('1.0', 'Congratulations! Player2 Win The Game!\n')
return
# 当玩家打出牌后,切换到电脑2,调用电脑出牌方法
self.cur_identify += 1
if self.cur_identify == 3:
self.cur_identify = 1
elif len(card_list_pc) == 0:
self.frm_M_text.insert('1.0', '没有大过玩家的牌,请玩家出牌\n')
#重置中间牌的大小
self.mid_num = -2
self.cur_identify = 1 # # 实例化一个sched对象
# schedule = sched.scheduler(time.time, time.sleep)
def show_time(self):
cur_time = time.strftime('%Y-%m-%d %X',time.localtime())
top_time_label = Label(self.frm_T, text=cur_time, font=('Arial', 16))
top_time_label.grid(column=2, sticky=N)
while True:
cur_time = time.strftime('%Y-%m-%d %X', time.localtime())
top_time_label.configure(text=cur_time)
time.sleep(1)
def main_start(self):
thd.Timer(0, self.show_time).start()
def main():
d = card2()
mainloop() if __name__ == '__main__':
main()
注意:调整图片大小需要用到resize()方法,PNG图片需要用到ImageTk.PhotoImage(self.img_resized)转化方可显示。
增加了定时任务显示当前时间,每秒切换一次,注意不要占用主线程。
提出几个方向以待大神们能完善:
2.1、程序中只启用了player2与玩家互动,可以尝试启用4个。
2.2、只选择了一组牌进行显示,可以尝试加入4组牌,用file文件引入数据。
2.3、不同花色的相同数字比较可以用3.1、3.2、3.3、3.4浮点数比较大小。
2.4、图片显示可以增加更多,遗留的问题是图片重叠显示,感觉用tkinter的grid方式无法实现,可能自己水平有限。
python-tkinter学习实例的更多相关文章
- Python Tkinter 学习成果:点歌软件music
笔者工作业余时间也没什么爱好,社交圈子也小,主要娱乐就是背着自己带电瓶的卖唱音响到住地附近找个人多的位置唱唱KtV. 硬件上点歌就用笔记本电脑,歌曲都是网上下载的mkv格式的含有两个音轨的视频.因此点 ...
- Python Tkinter学习笔记
介绍 入门实例 显示一个窗口,窗口里面有一个标签,显示文字 import tkinter as tk # 一个顶层窗口的实例(Top Level),也称为根窗口 app = tk.Tk() # 设置窗 ...
- Python tkinter 学习记录(一) --label 与 button
最简的形式 from tkinter import * root = Tk() # 创建一个Tk实例 root.wm_title("标题") # 修改标题 root.mainloo ...
- Python Tkinter学习(1)——第一个Tkinter程序
注:本文可转载,转载请注明出处:http://www.cnblogs.com/collectionne/p/6885066.html.格式修改未完成. Tkinter资料 Python Wiki, T ...
- Python Tkinter 学习历程 一
一丶一个简单的程序 from tkinter import * #引入所有类#查看tk版本#tkinter._test() root = Tk(); #对这个类进行实例化 w1 = Label(roo ...
- Python Tkinter小实例——模拟掷骰子
什么是Tkinter? Tkinter 是 Python 的标准 GUI 库.Python 使用 Tkinter 可以快速的创建 GUI 应用程序. 由于 Tkinter 是内置到 python 的安 ...
- python tkinter学习——tkinter部件1
tkinter部件 一.Tk() & Label() & Button() 1,Tk() 窗口 用Tk()创建窗口对象: #文件名:test1.py import tkinter as ...
- python tkinter学习——布局
目录 一.pack() 二.grid() 三.place() 四.Frame() 正文 布局 一.pack() pack()有以下几个常用属性: side padx pady ipadx ipady ...
- python GUI学习——Tkinter
支持python的常见GUI工具包: Tkinter 使用Tk平台 很容易得到 半标准 wxpython 基于wxWindows.跨平台越来越流行 Python Win 只能在Windows上使用 使 ...
- Python进阶学习之特殊方法实例详析
Python进阶学习之特殊方法实例详析 最近在学习python,学习到了一个之前没接触过的--特殊方法. 什么是特殊方法?当我们在设计一个类的时候,python中有一个用于初始化的方法$__init_ ...
随机推荐
- redis 中用正则找key
获取 redis 中所有的 key 可用使用 *. redis 127.0.0.1:6379> KEYS * 1) "w3c3" 2) "w3c1" 3) ...
- java基础-网络编程(Socket)技术选型入门之NIO技术
java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...
- Solr记录-solr文档xml
Solr添加文档(XML) 在上一章中,我们学习解释了如何向Solr中添加JSON和.CSV文件格式的数据.在本章中,将演示如何使用XML文档格式在Apache Solr索引中添加数据. 示例数据 假 ...
- CSS规范 - 最佳实践--(来自网易)
最佳选择器写法(模块) /* 这是某个模块 */ .m-nav{}/* 模块容器 */ .m-nav li,.m-nav a{}/* 先共性 优化组合 */ .m-nav li{}/* 后个性 语义化 ...
- 关于markdown文件插入图片遇到的小问题和解决办法
今天用md文件时候发现需要插入图片,以前没做过,所以写下来分享下. 1.先在自己的github上建一个仓库,里面新建个img文件夹存放图片,怎么建仓库可以上网找资料,这里就不详细说明了.建好的仓库如下 ...
- sublime text 3 开启卡顿(win7)解决办法
启动sublime3,ctrl+~打开命令窗口,输入以下 { "update<em>check": false, "font</em>size&q ...
- str函数
python2: a = str(unicode类对象) #str()函数如果接收的参数是unicode类,会转换为python的defaultencoding格式,所以,如果unicode类对象是汉 ...
- 高通Trustzone and QSEE介绍
http://blog.csdn.net/iamliuyanlei/article/details/52625968
- binlog2sql的安装及使用
binlog2sql是大众点评开源的一款用于解析binlog的工具,在测试环境试用了下,还不错. DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚.传统恢复方法 ...
- MyISAM引擎和InnoDB引擎的特点
随着MySQL的不断更新,由于各存储引擎功能特性差异较大,这篇文章主要是介绍如何来选择合适的存储引擎来应对不同的业务场景,朋友们可以根据业务需求,选择合适的存储引擎.^.^ MyISAM 特性 不支持 ...