You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:24:16