内容简介: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
贴上程序的源码,仅供参考:
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方式无法实现,可能自己水平有限。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 通过实例学习 tcpdump 命令
- Vue:学习笔记(二)-实例
- vue 源码学习 - 实例挂载
- 机器学习入门教程:启发式实例
- [边学边练]用简单实例学习React
- 零基础学习 Python 之细说类属性 & 实例
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
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》 这本书的介绍吧!