python-tkinter学习实例

栏目: Python · 发布时间: 6年前

内容简介:python-tkinter学习实例

在好友的邀请下,尝试用tkinter做一个卡牌的普通界面显示,正好练习下 python 的写法。

花了两天学习,写了两天代码,做了个最基本的demo。显示如下:

python-tkinter学习实例

其中需要引入的第三方库主要有,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安装

程序中用到的图片主要有:

python-tkinter学习实例

需要图片资源的小伙伴可以自行上git上下载:

https://github.com/ishikota/PyPokerGUI

pypokergui--server--static

贴上程序的源码,仅供参考:


  1 # -*- coding: utf-8 -*-
  2 from Tkinter import *
  3 from PIL import Image,ImageTk
  4 
  5 import Image,math,random,time,sched
  6 import threading as thd
  7 class card2:
  8     #定义全局变量
  9     #总牌数
 10     num_list = ['3', '4', '5', '6', '7', '8', '9','T', 'J','Q','K', 'A','2']
 11     # 全局变量纪录玩家当前要打出的牌数字
 12     #当前牌面字符串
 13     str_num = '';
 14     #当前牌面字符串在num_list中的位置
 15     index_num = -1;
 16     # 中间桌面上牌的大小
 17     mid_num = -2;
 18     #判断是否会生成重复的牌
 19     check_list = [];
 20     #记录当前回合数
 21     round_num = 1;
 22     #当前玩家手中牌位置
 23     cur_position = 0;
 24     #定义玩家当前手中牌的集合
 25     player_card_list = [];
 26     player1_card_list = [];
 27     player2_card_list = [];
 28     player3_card_list = [];
 29     player4_card_list = [];
 30 
 31     #变量判断玩家身份,默认为玩家
 32     cur_identify = 1;
 33 
 34     def __init__(self):
 35         self.tk = Tk()
 36         #tk.geometry('1200x1600')
 37         self.tk.title('A Easy Card Game')
 38 
 39         self.img = Image.open('images/poker_pot.png')
 40         self.w_box = 120
 41         self.h_box = 120
 42         self.w, self.h = self.img.size
 43         # w,h = img2.size
 44         # 缩放图像让它保持比例,同时限制在一个矩形框范围内
 45         self.img_resized = self.resize(self.w, self.h, self.w_box, self.h_box, self.img)
 46         self.photo = ImageTk.PhotoImage(self.img_resized)
 47         # frm_TL = Frame(bg = 'WHITE',width = 300, height = 200)
 48         self.frm_T = Frame(bg='white', width=300, height=200)
 49         self.frm_L = Frame(bg='white', width=300, height=400)
 50         self.frm_M = Frame(bg='white', width=200, height=400)
 51         self.frm_R = Frame(bg='white', width=300, height=400)
 52         self.frm_B = Frame(bg='white', width=400, height=200)
 53         # frm_TL.grid(row=0,column=0)
 54         self.frm_T.grid(row=0, column=1)
 55         self.frm_L.grid(row=1, column=0)
 56         self.frm_M.grid(row=1, column=1)
 57         self.frm_R.grid(row=1, column=2)
 58         self.frm_B.grid(row=2, column=1)
 59         # Top
 60         Label(self.frm_T, text="Player3", font=('Arial', 16)).grid(column=1, sticky=N)
 61         Button(self.frm_T, text="重新发牌", command=self.replay, width=8, height=1,
 62                font=('Arial', 16)).grid(row=0, column=3)
 63         self.frm_T_label_L = Label(self.frm_T, image=self.photo)
 64         self.frm_T_label_L.image = self.photo
 65         self.frm_T_label_L.grid(row=1, column=0, sticky=E)
 66         # frm_T_label_L.grid(row=1,column=1,columnspan=2,rowspan=2,sticky=W+E+N+S,padx=5,pady=5)
 67         self.frm_T_label_M = Label(self.frm_T, image=self.photo)
 68         self.frm_T_label_M.image = self.photo
 69         self.frm_T_label_M.grid(row=1, column=1,padx=10, sticky=E)
 70         self.frm_T_label_R = Label(self.frm_T, image=self.photo)
 71         self.frm_T_label_R.image = self.photo
 72         self.frm_T_label_R.grid(row=1, column=2, sticky=E)
 73 
 74         # Left
 75         Label(self.frm_L, text="Player4", font=('Arial', 16)).grid(row=1, column=0, sticky=N)
 76         self.frm_L_label_T = Label(self.frm_L, image=self.photo)
 77         self.frm_L_label_T.image = self.photo
 78         self.frm_L_label_T.grid(row=0, column=1, sticky=E)
 79         self.frm_L_label_T = Label(self.frm_L, image=self.photo)
 80         self.frm_L_label_T.image = self.photo
 81         self.frm_L_label_T.grid(row=1, column=1, sticky=E)
 82         self.frm_L_label_T = Label(self.frm_L, image=self.photo)
 83         self.frm_L_label_T.image = self.photo
 84         self.frm_L_label_T.grid(row=2, column=1, sticky=E)
 85 
 86         # Middle
 87         self.frm_M_label_T = Label(self.frm_M, image=self.photo)
 88         self.frm_M_label_T.image = self.photo
 89         self.frm_M_label_T.grid(row=1, column=0, sticky=E)
 90         self.frm_M_text = Text(self.frm_M, width=30, height=6, bg='Green', font=('Verdana', 15))
 91 
 92         #self.frm_M_text.insert('1.0', 'this is '+str(self.round_num)+' round\n')
 93         #self.frm_M_text.insert(END, 'last round')
 94         self.frm_M_text.grid(row=2, column=0, columnspan=2)
 95 
 96         # Right  frm_R
 97         self.frm_R_label_T = Label(self.frm_R, image=self.photo)
 98         self.frm_R_label_T.image = self.photo
 99         self.frm_R_label_T.grid(row=0, column=0, sticky=E)
100         self.frm_R_label_T = Label(self.frm_R, image=self.photo)
101         self.frm_R_label_T.image = self.photo
102         self.frm_R_label_T.grid(row=1, column=0, sticky=E)
103         self.frm_R_label_T = Label(self.frm_R, image=self.photo)
104         self.frm_R_label_T.image = self.photo
105         self.frm_R_label_T.grid(row=2, column=0, sticky=E)
106         Label(self.frm_R, text="Player2", font=('Arial', 16)).grid(row=1, column=1, sticky=N)
107 
108         # 初始化玩家手中牌
109         self.load_sys()
110 
111         self.main_start()
112 
113         self.frm_B_label_T_4 = Label(self.frm_B, image=self.photo)
114         self.frm_B_label_T_4.image = self.photo
115         self.frm_B_label_T_4.grid(row=0, column=3, sticky=E)
116         Label(self.frm_B, text="Player1", font=('Arial', 16)).grid(row=1, column=1, sticky=N)
117         Button(self.frm_B, text="出牌", command=self.discard, width=6, height=1,
118                font=('Arial', 16)).grid(row=1, column=3)
119         Button(self.frm_B, text="PASS", command=self.player_pass, width=6, height=1,
120                font=('Arial', 16)).grid(row=1, column=4)
121 
122     def resize(self,w, h, w_box, h_box, pil_image):
123         '''''
124         resize a pil_image object so it will fit into
125         a box of size w_box times h_box, but retain aspect ratio
126         对一个pil_image对象进行缩放,让它在一个矩形框内,还能保持比例
127         '''
128 
129         f1 = 1.0 * w_box / w  # 1.0 forces float division in Python2
130         f2 = 1.0 * h_box / h
131         factor = min([f1, f2])
132         # print(f1, f2, factor) # test
133         # use best down-sizing filter
134         width = int(w * factor)
135         height = int(h * factor)
136         return pil_image.resize((width, height), Image.ANTIALIAS)
137     def replay(self):
138         self.load_sys()
139 
140     #初始化玩家手中牌
141     def load_sys(self):
142         # 初始化当前玩家手中牌集合,先重置
143         self.player1_card_list = []
144         self.player2_card_list = []
145         self.check_list = []
146         self.cur_identify = 1
147         for i in range(3):
148             num = random.randint(0,12)
149             #判断是否生成重复的牌,去重
150             while self.check_list.__contains__(num):
151                 num = random.randint(0, 12)
152             cur_str = self.num_list[num]
153             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')))
154             frm_B_label_T_1 = Label(self.frm_B, image=photo_current)
155             frm_B_label_T_1.image = photo_current
156             frm_B_label_T_1.grid(row=0, column=i,sticky=E)
157             frm_B_label_T_1.bind('<ButtonRelease-1>', self.handlerAdaptor(self.choose, cur_str,i))
158             self.check_list.append(num)
159             self.player1_card_list.append(cur_str)
160             #生成玩家2手中的牌
161             num2 = random.randint(0, 12)
162             # 判断是否生成重复的牌,去重
163             while self.check_list.__contains__(num2):
164                 num2 = random.randint(0, 12)
165             cur_str2 = self.num_list[num2]
166             self.check_list.append(num2)
167             self.player2_card_list.append(cur_str2)
168 
169         print(self.player1_card_list)
170         print(self.player2_card_list)
171         #记录当前轮数并递增
172         self.frm_M_text.insert('1.0', 'this is ' + str(self.round_num) + ' round\n')
173         self.round_num+=1
174 
175         # 清空桌面上的牌
176         frm_M_label_T = Label(self.frm_M, image=self.photo)
177         frm_M_label_T.image = self.photo
178         frm_M_label_T.grid(row=1, column=0, sticky=E)
179         # 重置玩家手中当前牌
180         frm_B_label_T_4 = Label(self.frm_B, image=self.photo)
181         frm_B_label_T_4.image = self.photo
182         frm_B_label_T_4.grid(row=0, column=3, sticky=E)
183         #重置桌面上牌的大小
184         self.mid_num = -2
185     # Bottom
186     def choose(self,event,a,position):
187         self.frm_M_text.insert('1.0','Now Your Card Is C'+str(a)+'\n')
188         photo_cur = ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box, Image.open('images/card_C' + str(a) + '.png')))
189         frm_B_label_T_4 = Label(self.frm_B, image=photo_cur)
190         frm_B_label_T_4.image = photo_cur
191         frm_B_label_T_4.grid(row=0, column=3, sticky=E)
192         self.str_num = a
193         self.cur_position = position
194     def handlerAdaptor(self,fun, *kwds):
195         '''''事件处理函数的适配器,相当于中介,此处接收2个参数,那个event是从那里来的呢,我也纳闷,这也许就是python的伟大之处吧'''
196         return lambda event,fun=fun,kwds=kwds: fun(event, *kwds)
197     def discard(self):
198         if self.cur_identify == 1:
199             if self.str_num != '':
200                 self.index_num = self.num_list.index(self.str_num)
201             if self.index_num == -1:
202                 self.frm_M_text.insert('1.0','请选择一张牌\n')
203                 #return '请选择一张牌'
204             #判断要打出的牌与桌面上的牌大小
205             elif self.index_num <= self.mid_num:
206                 self.frm_M_text.insert('1.0', '请选择一张大牌\n')
207                # return '请选择一张大牌'
208             else:
209                 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')))
210                 frm_M_label_T = Label(self.frm_M, image=photo_mid)
211                 frm_M_label_T.image = photo_mid
212                 frm_M_label_T.grid(row=1, column=0, sticky=E)
213                 #清空玩家手中当前牌
214                 frm_B_label_T_4 = Label(self.frm_B, image=self.photo)
215                 frm_B_label_T_4.image = self.photo
216                 frm_B_label_T_4.grid(row=0, column=3, sticky=E)
217                 #frm_B_label_T_4.grid_forget()
218                 #给当前桌面牌赋值
219                 self.mid_num = self.index_num
220                 #重置玩家手中牌
221                 frm_B_label_T_X = Label(self.frm_B, image=self.photo)
222                 frm_B_label_T_X.image = self.photo
223                 frm_B_label_T_X.grid(row=0, column=self.cur_position, sticky=E)
224                 self.frm_M_text.insert('1.0', 'Player1 Play The Card!'+ str(self.str_num) +'\n')
225                 self.player1_card_list.remove(self.str_num)
226                 if self.player1_card_list.__len__() == 0:
227                     self.frm_M_text.insert('1.0', 'Congratulations! Player1 Win The Game!\n')
228                     return
229                 #当玩家打出牌后,切换到电脑2,调用电脑出牌方法
230                 self.cur_identify +=1
231                 self.discard_pc(self.cur_identify)
232         else:
233             self.frm_M_text.insert('1.0', '请等待其它玩家出牌\n')
234 
235     #没有可出的牌,切换到下一个对手
236     def player_pass(self):
237         # 重置中间牌的大小
238         self.mid_num = -2
239         #切换玩家
240         self.cur_identify += 1
241         self.discard_pc(self.cur_identify)
242 
243     # def player_pc(self,iden):
244     #     if iden == 2:
245     #         self.player_card_list = self.player2_card_list
246     #
247     #     if iden ==3:
248     #         self.cur_identify = 1
249 
250     def discard_pc(self,iden):
251         card_list_pc = []
252         if iden == 2:
253             for i in range(self.player2_card_list.__len__()):
254                 #将当前牌转化成索引号进行比较大小
255                 self.index_pc_num = self.num_list.index(self.player2_card_list[i])
256 
257                 if self.index_pc_num > self.mid_num:
258                     card_list_pc.append(self.player2_card_list[i])
259             card_list_pc.sort()
260             if len(card_list_pc) > 0:
261                 self.index_pc_num_temp = self.num_list.index(card_list_pc[0])
262                 self.mid_num = self.index_pc_num_temp
263                 photo_mid = ImageTk.PhotoImage(self.resize(self.w, self.h, self.w_box, self.h_box,
264                                                            Image.open('images/card_C' + str(card_list_pc[0]) + '.png')))
265                 frm_M_label_T = Label(self.frm_M, image=photo_mid)
266                 frm_M_label_T.image = photo_mid
267                 frm_M_label_T.grid(row=1, column=0, sticky=E)
268                 self.frm_M_text.insert('1.0', 'Player2 Play The Card!' + str(card_list_pc[0]) + '\n')
269                 self.player2_card_list.remove(card_list_pc[0])
270 
271                 if self.player2_card_list.__len__() == 0:
272                     self.frm_M_text.insert('1.0', 'Congratulations! Player2 Win The Game!\n')
273                     return
274                 # 当玩家打出牌后,切换到电脑2,调用电脑出牌方法
275                 self.cur_identify += 1
276                 if self.cur_identify == 3:
277                     self.cur_identify = 1
278             elif len(card_list_pc) == 0:
279                 self.frm_M_text.insert('1.0', '没有大过玩家的牌,请玩家出牌\n')
280                 #重置中间牌的大小
281                 self.mid_num = -2
282                 self.cur_identify = 1
283 
284     # # 实例化一个sched对象
285     # schedule = sched.scheduler(time.time, time.sleep)
286     def show_time(self):
287         cur_time = time.strftime('%Y-%m-%d %X',time.localtime())
288         top_time_label = Label(self.frm_T, text=cur_time, font=('Arial', 16))
289         top_time_label.grid(column=2, sticky=N)
290         while True:
291             cur_time = time.strftime('%Y-%m-%d %X', time.localtime())
292             top_time_label.configure(text=cur_time)
293             time.sleep(1)
294     def main_start(self):
295         thd.Timer(0, self.show_time).start()
296 def main():
297     d = card2()
298     mainloop()
299 
300 if __name__ == '__main__':
301     main()

View Code

注意:调整图片大小需要用到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方式无法实现,可能自己水平有限。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Usability for the Web

Usability for the Web

Tom Brinck、Darren Gergle、Scott D. Wood / Morgan Kaufmann / 2001-10-15 / USD 65.95

Every stage in the design of a new web site is an opportunity to meet or miss deadlines and budgetary goals. Every stage is an opportunity to boost or undercut the site's usability. Thi......一起来看看 《Usability for the Web》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码