Python GUI案例之看圖猜成語開發(第一篇)
Python GUI案例之看圖猜成語開發(第二篇)
Python GUI案例之看圖猜成語開發(完結篇)
我們將要實現這些功能:
(素材提取:https://download.csdn.net/download/qq_59142194/85827790)
終於來到第三篇了!!!
在這裡我們將實現自定義有多少個關卡數,16個漢字提示(12個隨機生成的干擾漢字),游戲通關記錄所用的時間,主要要注意下面3個的實現功能。
自定義關卡數
在自定義關卡數時(默認10關),我們需要在游戲選擇模式頁面中點擊闖關模式後添加ttkbootstrap裡面的一個查詢框Querybox,然後根據提示輸入關卡數後則將進入游戲闖關模式頁面。
def game_chuangguan_mode(self,event):
# 默認10個關卡(initialvalue=10)
number = Querybox.get_integer(prompt="請設置關卡數量:",title="自定義關卡數量 ",initialvalue=10,minvalue=0,maxvalue=50)
if number:
self.frame.destroy()
game_chuangguan_page(self.nickname,number)
① 創建四個用於顯示選擇結果的標簽,在這裡還要定義一個self.answer_list 列表來裝下生成的標簽對象,以便後面在標簽上配置文字configure()。
# 創建四個用於選擇結果的標簽
def create_selection_result_label(self):
self.answer_list = []
for i in range(4):
label = ttk.Label(self.canvas, text='', font=("微軟雅黑", 35), background='', width=2, cursor='hand2')
label.place(x=130 + i * 100, y=450)
self.answer_list.append(label)
重選按鈕,點擊執行後就會將self.answer_list 列表裡面的標簽對象全部摧毀後重新創建。
# 重選
def update_label(self):
self.CLICKTIMES = 0
self.TRUEANSWER = ''
for i in self.answer_list:i.destroy()
self.create_selection_result_label()
② 創建用於選擇文字內容的16個標簽(4 x 4),其中將有12個干擾文字,並且在創建標簽時還要為每一個標簽對象綁定一個鼠標點擊事件click_label(event)。
# 創建用於選擇文字內容的標簽
def create_option_text_label(self):
def click_label(event):
if self.CLICKTIMES < 4:
self.CLICKTIMES += 1
label_text = event.widget["text"] # 得到標簽上的文本
self.answer(label_text)
self.label_oop_list = []
# 設置4行4列的標簽
for i in range(4):
for j in range(4):
label = ttk.Label(self.canvas, text='', font=("微軟雅黑", 35), background='#FFFAE3', width=2,cursor='hand2')
label.place(x=510 + j * 100, y=90 + i * 95)
label.bind("<Button-1>", click_label)
self.label_oop_list.append(label)
這裡也比較重要的部分,變量IDX記錄第幾關,loading_idiom_img()方法裡面的for循環則是為前面創建的16個文字標簽配置文字(包括
正確的4個文字([i for i in self.idiom])和
12個干擾文字(disturb_text_list ))
IDX = 1 # 第幾關,默認第1關
# 加載成語圖片
def loading_idiom_img(self,):
self.idiom = self.idiom_list[self.IDX - 1].split('.')[0]
print('答案:', self.idiom)
disturb_text_list = [self.GBK2312() for i in range(12)] # 隨機生成12個干擾漢字
disturb_text_list.extend([i for i in self.idiom])
for label_oop in self.label_oop_list:
text = random.choice(disturb_text_list)
disturb_text_list.remove(text)
label_oop.configure(text=text)
self.guanqia_lable.config(text=f'第 {
self.IDX} / {
len(self.idiom_list)}關')
self.idiom_img = ttk.PhotoImage(file=f'../看圖猜成語/{
self.idiom}.png')
self.lm.configure(image=self.idiom_img)
隨機生成干擾文字
# 隨機生成一個漢字
def GBK2312(self, ):
head = random.randint(0xb0, 0xf7)
body = random.randint(0xa1, 0xfe)
val = f'{
head:x}{
body:x}'
str = bytes.fromhex(val).decode('gb2312')
return str
③ 記錄時間,這裡的寫法與前面的動態移動原理都一樣,都是由after()實現,間隔1秒刷新標簽(time_label )一次。self.flag = True 為定義一個信號量,用於當我們完成游戲通過時,run()結束循環
# 記錄通關所耗時
def recording_time(self):
self.flag = True # 定義一個信號量,用於當我們完成游戲通過時,run()結束循環
time_label = ttk.Label(self.canvas,text='時長:00:00:00', font=("華文行楷", 15), background='#DAEFE6',bootstyle=DANGER)
time_label.place(x=730,y=50)
start_time = datetime.datetime.now()
def run():
if self.flag:
time_label.after(1000, run)
update_time = datetime.datetime.now() - start_time
self.time_ =f'時長:{
update_time}'.split('.')[0]
time_label.configure(text=self.time_) # 不顯示時長的毫秒值
run()
提示回答是否正確,這裡用了一點線程的知識,回答正確線程啟動提示“回答正確”標簽,3秒後將自動消失;回答錯誤,同理。
t = threading.Thread(target=self.dispaly_answer_result, args=('回\n答\n錯\n誤',))
t.setDaemon(True)
t.start()
# 顯示回答結果是否正確
def dispaly_answer_result(self,text):
self.result_label.configure(text=text)
time.sleep(3)
try: self.result_label.configure(text='')
except Exception as e: print(e)