Home > Blockchain >  Trying to destroy a class Frame in tKinter GUI
Trying to destroy a class Frame in tKinter GUI

Time:05-16

I'm trying to simulate a GUI as part of a larger card game, using python's tKinter. This GUI asks the user to enter a desired number of cards, press the deal button, and then it updates the buttons on the screen to display a random deck of that number of cards (as buttons). My issue is that each time the deal button is pressed, the new card buttons are simply added to the old ones. I have tried to incorporate a Destroy method under the myButtons class, and then calling the method each time the 'Deal' button is clicked, but this does not seem to work either.

import random
from tkinter import *


root = Tk()

def deal(n):
    deck = Deck()
    deck.shuffle()
    cards = []
    for number in range(n):
        card = deck.deal()
        cards.append(card)
    return cards


class myButtons(Frame):

    def __init__(self, parent, Cards):
        Frame.__init__(self, parent)

        self.Cards = Cards

        for Card in Cards:
            self.SingleButton = Button(self)
            self.SingleButton['text'] = Card
            self.SingleButton.pack()

class Card:
    def __init__(self, f, s):
        self.myFaceValue = f
        self.mySuit = s
    def __str__(self):
        return self.myFaceValue   ' of '   self.mySuit
    def faceValue(self):
        return self.myFaceValue
    def suit(self):
        return self.mySuit

class Deck:
    faceValues = ['ace', '2', '3', '4', '5', '6', '7', '8',
                  '9', '10', 'jack', 'queen', 'king']
    suits = ['clubs', 'diamonds', 'hearts', 'spades']
    def __init__(self):
        self.theCards = [Card(faceValue, suit)
                         for faceValue in Deck.faceValues
                         for suit in Deck.suits]
        self.shuffle()
    def shuffle(self):
        random.shuffle(self.theCards)
    def deal(self):
        return self.theCards.pop()
    def cardsLeft(self):
        return len(self.theCards)

class enhancedEntry(Frame):
    def __init__(self, parent, prompt, actionText, action):
        Frame.__init__(self, parent)

        self.inputBoxLabel = Label(self)
        self.inputBoxLabel['text'] = prompt
        self.inputBoxLabel.pack(side=LEFT, fill=X)

        self.inputBox = Entry(self)
        self.inputBox.pack(side=LEFT, fill=X)

        self.button = Button(self)
        self.button['text'] = actionText
        self.button['command'] = action

        self.button.pack(side=LEFT, fill=X)

    def get(self):
        return self.inputBox.get()

    def setActionText(self, actionText):
         self.button['text'] = actionText

    def setPrompt(self, prompt):
        self.inputBoxLabel['text'] = prompt

    def setAction(self, cmd):
        self.button['command'] = cmd

def dealCards():
    #reset myButtonsFrame
    myButtons.destroy
    
    num = userInput.get()
    if num.isdigit():
        number = int(num)

        if 0<number<=52:
            myCards = deal(number)
            displayedButtons = myButtons(root, myCards)
            displayedButtons.pack()

    else:
        input('This is not a number')
        return

userInput = enhancedEntry(root, 'Enter # of cards:', 'Deal', dealCards)
userInput.pack(fill=X)

mainloop()

How can I use the destroy function to destroy the myButtons class Frame each time the 'Deal' button is clicked such that is can reset/refresh the GUI to display only the desired number of cards?

CodePudding user response:

I believe you can use the function pack_forget().

widget.pack_forget()

This should remove the widget from the window

CodePudding user response:

It is better to create instance of myButtons without any button inside first, then remove existing buttons and create the required number of buttons after user inputs the number.

...

class myButtons(Frame):
    # create number of cards given
    def deal(self, Cards):
        self.Cards = Cards
        for Card in Cards:
            Button(self, text=Card, width=20).pack()
...

def dealCards():
    # delete existing buttons
    for w in displayedButtons.winfo_children():
        w.destroy()

    num = userInput.get()
    if num.isdigit():
        number = int(num)

        if 0<number<=52:
            myCards = deal(number)
            displayedButtons.deal(myCards)

    else:
        input('This is not a number')
        return

userInput = enhancedEntry(root, 'Enter # of cards:', 'Deal', dealCards)
userInput.pack(fill=X)

# create instance of myButtons without any button inside
displayedButtons = myButtons(root)
displayedButtons.pack()

root.mainloop()
  • Related