Function to name: LabelFrame [SOLVED]

As a learning exercise, I’m coding a Blackjack game which will, in time, follow the correct rules of Blackjack. I have a basic GUI in place, with a single player and I’ve solved all issues related to creating and displaying cards, calculating point and so on.

I now want to add ‘house’ with which to play against. It seems to me (correct me if I’m wrong) that the cardsFrame is a good candidate for a class. I could then pass to said class the string 'Player' or 'House' and have class process the cardsFrame = part of the script, which the main script would then place with a relative adjustment to rely

It could be that I don’t need to use class, but I do want to learn how to use class.

For now, I feel I need to get this to work with a Function, which could then become a part of a class, but I’m stuck on the first hop: how to have a Function construct a LabelFrame with a unique name (one for ‘House’ and one for ‘Player’).

This code is a stripped out working model that simply demonstrates what I’m trying to do, aside from it only constructs a single LabelFrame named cardsFrame, but I need it to be a unique name, such as player_cardsFrame and house_cardsFrame.

Excuse the Function being named it – it’s simply a working name.

#!/usr/bin/python3

from tkinter import *
bgColor = "#006400"
cardFrame_w = 400
cardHeight = 80

def it(name):
    global cardsFrame
    cardsFrame = LabelFrame(tableFrame, width=cardFrame_w, height=cardHeight+30, bg=bgColor, text=name)

root = Tk()

root.geometry("800x400")
root.title("Blackjack")
root.resizable(False, False)

# table set-up
tableFrame = Frame(root, width=800, height=400, bg=bgColor)
tableFrame.place(relx = 0.001, rely = 0.001)

# card container set-up
name = input("Name: ")

it(name)

'''this has been moved to a Function
cardsFrame = LabelFrame(tableFrame, width=cardFrame_w, height=cardHeight+30, bg=bgColor, text=name)
'''
cardsFrame.place(relx=0.01, rely=0.02)

root.mainloop()

By making cardsFrame a global, you can have only one frame, and you want more. So we remove that.

Now how can we have more frames? We return a new one from the function and store it with a name or in a list. I took as an example one player and the house:

from tkinter import *
bgColor = "#006400"
cardFrame_w = 400
cardHeight = 80

def create_card_frame(name):
    cardsFrame = LabelFrame(tableFrame, width=cardFrame_w, height=cardHeight+30, bg=bgColor, text=name)
    return cardsFrame

root = Tk()

root.geometry("800x400")
root.title("Blackjack")
root.resizable(False, False)

# table set-up
tableFrame = Frame(root, width=800, height=400, bg=bgColor)
tableFrame.grid(row=0, column=0)

# card container set-up
name = input("Name: ")
player_frame = create_card_frame(name)
player_frame.grid(row=0, column=0)
house_frame = create_card_frame("House")
house_frame.grid(row=1, column=0)

root.mainloop()

Remarks:

  • I named the function create_card_frame, because that is what (I think) it does

  • Don’t mind the change to the grid layout manager, I never worked with place

  • The layout got a bit nasty, but I did not think it got in the way of the understanding, so I left it.

Hope this helps.

Thank you.

Yes, that was my thoughts also: I plan on having this as a network based game, with new players joining and leaving at will, but that’s a ways down the road yet.

I know what you mean regarding .grid() as that was my first approach: I got it to work just fine with Canvas but when I realized the project was becoming way to complicated (I wanted actual images of the cards) and scaled it back to simple Frames, the .grid() method fell apart; more to my lack of skills than anything else.

I’ll merge this in to my dev code and see if it’ll work: on the face of it I see no reason for it not to.

My thanks for your time and help.

edit: I was thinking that I could get way with just the one .place() statement, but maybe it’s either not possible or it will get overly complex to do that.

During a redesign, I’ve taken a different approach which has resulted in this way of coding the cards and placement:

pid = 1  # player id number

if pid == 0:
    cardF = ttk.Frame(house_cardsFrame, width=cardWidth, height=cardHeight)

if pid == 1:
    cardF = ttk.Frame(player_cardsFrame, width=cardWidth, height=cardHeight)

cardF.place(relx = card_relx, rely = 0.0)
cardT = text=card[0]
cardL = ttk.Label(cardF, text = cardT, font=('calibre',20),foreground=textColor)
cardL.place(relx = 0.5, rely = 0.5, anchor = CENTER)

Now, I can reuse that code for any card and any player by simply changing the relx and rely, based on the pid.