Tkinter按钮点击无响应,关闭窗口后才执行卡牌对战游戏求助
问题原因分析
- Tkinter主循环阻塞后续代码:
window.mainloop()会持续运行直到窗口关闭,它后面的Card/Suit类定义、牌组创建、游戏逻辑代码都要等窗口关闭才会执行。这导致点击按钮时,create_deck从未运行过,partial_deck是空的,deal_war根本无法执行有效操作。 - 类与变量初始化顺序错误:
Card和Suit类定义在主循环之后,create_deck调用时这两个类还不存在,会直接触发错误(只是被主循环阻塞没显示);同时全局变量重复定义,初始值被覆盖,进一步导致逻辑失效。 - 按钮点击逻辑不完整:当前
click仅调用deal_war,没有执行胜负判断的输出逻辑,就算牌组初始化正确,点击后也看不到任何结果。
修正后的代码
from random import randint from enum import Enum, IntEnum from tkinter import Tk, Button class Card(IntEnum): TWO = 2 THREE = 3 FOUR = 4 FIVE = 5 SIX = 6 SEVEN = 7 EIGHT = 8 NINE = 9 TEN = 10 JACK = 11 QUEEN = 12 KING = 13 ACE = 14 class Suit(Enum): SPADES = 'spades' CLUBS = 'clubs' HEARTS = 'hearts' DIAMONDS = 'diamonds' class PlayingCard: def __init__(self, card_value, card_suit): self.card = card_value self.suit = card_suit full_deck = [] partial_deck = [] player1_cards = [] player2_cards = [] def create_deck(): global full_deck full_deck.clear() for suit in Suit: for card in Card: full_deck.append(PlayingCard(card, suit)) return full_deck def deal_war(): global partial_deck, player1_cards, player2_cards player1_cards.clear() player2_cards.clear() partial_deck = list(full_deck) while len(partial_deck) > 0: player1_cards.append(draw_card(partial_deck)) if len(partial_deck) > 0: player2_cards.append(draw_card(partial_deck)) def draw_card(deck): rand_card = randint(0, len(deck) - 1) return deck.pop(rand_card) def click(): create_deck() deal_war() for i in range(min(len(player1_cards), len(player2_cards))): p1_card = player1_cards[i] p2_card = player2_cards[i] if p1_card.card > p2_card.card: print(f"Player 1 wins with: {p1_card.card.name} of {p1_card.suit.value}") print(f"Player 2 loses with: {p2_card.card.name} of {p2_card.suit.value}") elif p1_card.card < p2_card.card: print(f"Player 2 wins with: {p2_card.card.name} of {p2_card.suit.value}") print(f"Player 1 loses with: {p1_card.card.name} of {p1_card.suit.value}") else: print(f"WAR! Both played {p1_card.card.name} of {p1_card.suit.value} vs {p2_card.card.name} of {p2_card.suit.value}") print("--- 本轮结束 ---") window = Tk() button = Button(window, text='Start War Game', padx=20, pady=20, command=click) button.pack() window.mainloop()
关键修改说明
- 将
Card、Suit类和全局变量移到主循环前,确保函数调用时依赖的类已存在。 - 用
global关键字声明全局变量,避免局部变量覆盖全局值。 - 完善
click函数:每次点击都重新创建牌组、发牌,并立即输出胜负结果。 - 修复牌数为奇数时的索引越界问题,优化输出信息使其更直观。
内容的提问来源于stack exchange,提问作者Jacobrm84
相关产品推荐
相关产品推荐

