Python Forum
Python3 tkinter radiobutton problem - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: GUI (https://python-forum.io/forum-10.html)
+--- Thread: Python3 tkinter radiobutton problem (/thread-32491.html)

Pages: 1 2


Python3 tkinter radiobutton problem - Nick_tkinter - Feb-12-2021

Hello guys. I have a small problem with my app(It's not big ,just for experience).
As you can see in the first photo ,when I start my program ,all radiobuttons has a gray color inside(Its not selected),but it has no the default white color I want.When I select a choice,it's white(ok) .So,how can I fix this problem?
Also, as you can see in the 2nd photo when (for example) choose "orange juice" (a big word) and then I choose "Meat" (small word) ,the printing of the word is not obvious. How can I fix this problem?

1st photo
2nd photo

Code:
from tkinter import *

root = Tk()
root.title("Super Market")
root.geometry("1500x1300")

food = [
        ("Rice" , 0.99) ,                       # value for radio_button -> 1
        ("Spaghetti" , 0.95) ,                  # value for radio_button -> 2
        ("Ice cream" , 3.44) ,                  # value for radio_button -> 3
        ("Pizza" , 7.50) ,                      # value for radio_button -> 4
        ("Cheese" , 2.10) ,                     # value for radio_button -> 5
        ("Cheddar" , 0.45) ,                    # value for radio_button -> 6
        ("Cherry" , 0.88) ,                     # value for radio_button -> 7
        ("Banana" , 0.40) ,                     # value for radio_button -> 8
        ("Apple" , 0.67) ,                      # value for radio_button -> 9
        ("Meat" , 7.28) ,                       # value for radio_button -> 10
        ("Fish" , 9.72) ,                       # value for radio_button -> 11
        ("Orange" , 0.62) ,                     # value for radio_button -> 12
        ("Orange juice" , 2.10) ,               # value for radio_button -> 13
        ("Chocolate" , 0.99) ,                  # value for radio_button -> 14
        ("Bread" , 0.55)                        # value for radio_button -> 15
       ]


food_name_var = StringVar()

frame = LabelFrame(root , relief = SUNKEN , bd = 1)
frame.grid(row = 0 , column = 0 , sticky = W)

r = 0
for food_name , food_price in food:
        Radiobutton(frame , text = food_name , variable = food_name_var , value = r+1 , padx = 10 , pady = 5).grid(row = r , column = 0 , sticky = W)
        label_price = LabelFrame(root , relief = SUNKEN , bd = 1 , text = "Price")
        label_price.grid(row = r , column = 1 , sticky = W)
        r += 1
        

def select_food(food_name):
        label_print_food = Label(root , text = food_name)
        label_print_food.grid(row = 0 , column = 4)
        

button = Button(root , text = "Basket" , command = lambda: select_food(food[ int(food_name_var.get() ) - 1][0]) )
button.grid(row = 0 , column = 3)


root.mainloop()
Thanks in advance Smile


RE: Python3 tkinter radiobutton problem - deanhystad - Feb-12-2021

You need an IntVar(), not a StringVar(). You can use either IntVar() or StringVar(), but the variable type must match the value type.

This code uses a StringVar() and sets the RadioButton value to the food name. Since the button values are food names it makes more sens for food to be a dictionary with the name as the key.
root.geometry("1500x1300")

food = {
    "Rice": 0.99,
    "Spaghetti": 0.95,
    "Ice cream": 3.44,
    "Pizza": 7.50,
    "Cheese": 2.10, 
    "Cheddar": 0.45, 
    "Cherry": 0.88, 
    "Banana": 0.40, 
    "Apple": 0.67, 
    "Meat": 7.28, 
    "Fish": 9.72, 
    "Orange": 0.62, 
    "Orange juice": 2.10, 
    "Chocolate": 0.99, 
    "Bread": 0.55}

frame = tk.LabelFrame(root, relief=tk.SUNKEN, bd=1)
frame.grid(row=0 ,column=0, sticky=tk.W)

food_var = tk.StringVar()
food_var.set(list(food)[0])
for r, name in enumerate(food):
    tk.Radiobutton(frame , text=name, variable=food_var, value=name, padx=10, pady=5) \
        .grid(row=r+1, column=0 , sticky=tk.W)
    label_price = tk.LabelFrame(root, relief=tk.SUNKEN, bd=1, text="Price")
    label_price.grid(row=r+1, column=1, sticky=tk.W)

def select_food(food_name):
    tk.Label(grocery_list, text=food_name).pack(side=tk.TOP)

button = tk.Button(root, text="Basket", command=lambda: select_food(food_var.get()))
button.grid(row=0, column=3)
grocery_list = tk.Frame(root)
grocery_list.grid(row=0, column=4)

root.mainloop()



RE: Python3 tkinter radiobutton problem - BashBedlam - Feb-12-2021

I've modified your code so that select_food () re-configures label_print_food instead of recreating it each time. That takes care of the second problem. I inserted food_name_var.set ("Bread") after food_name_var = StringVar() and that should turn all of the buttons white like you wanted. Here's the altered code :

from tkinter import *
 
root = Tk()
root.title("Super Market")
root.geometry("1500x1300")
 
food = [
        ("Rice" , 0.99) ,                       # value for radio_button -> 1
        ("Spaghetti" , 0.95) ,                  # value for radio_button -> 2
        ("Ice cream" , 3.44) ,                  # value for radio_button -> 3
        ("Pizza" , 7.50) ,                      # value for radio_button -> 4
        ("Cheese" , 2.10) ,                     # value for radio_button -> 5
        ("Cheddar" , 0.45) ,                    # value for radio_button -> 6
        ("Cherry" , 0.88) ,                     # value for radio_button -> 7
        ("Banana" , 0.40) ,                     # value for radio_button -> 8
        ("Apple" , 0.67) ,                      # value for radio_button -> 9
        ("Meat" , 7.28) ,                       # value for radio_button -> 10
        ("Fish" , 9.72) ,                       # value for radio_button -> 11
        ("Orange" , 0.62) ,                     # value for radio_button -> 12
        ("Orange juice" , 2.10) ,               # value for radio_button -> 13
        ("Chocolate" , 0.99) ,                  # value for radio_button -> 14
        ("Bread" , 0.55)                        # value for radio_button -> 15
       ]
 
 
food_name_var = StringVar()
food_name_var.set ("Bread")
frame = LabelFrame(root , relief = SUNKEN , bd = 1)
frame.grid(row = 0 , column = 0 , sticky = W)
 
r = 0
for food_name , food_price in food:
        Radiobutton(frame , text = food_name , variable = food_name_var , value = r+1 , padx = 10 , pady = 5).grid(row = r , column = 0 , sticky = W)
        label_price = LabelFrame(root , relief = SUNKEN , bd = 1 , text = "Price")
        label_price.grid(row = r , column = 1 , sticky = W)
        r += 1
 
def select_food(food_name):
        label_print_food.configure (text = food_name)
 

button = Button(root , text = "Basket" , command = lambda: select_food(food[ int(food_name_var.get() ) - 1][0]) )
button.grid(row = 0 , column = 3)
label_print_food = Label(root , text = '')
label_print_food.grid(row = 0 , column = 4)
 
root.mainloop()



RE: Python3 tkinter radiobutton problem - Nick_tkinter - Feb-12-2021

Hello again. I have some problems with my app. I want it to look something like this
Also ,I have a frame as you can see on the right side.So, when I click an item, I want to add it to the basket(Done),but the problem is that the item doesn't place down the previous one.( See here )

I also want to put "remove" buttons right from added items to remove items from list ,but this doesn't seem to work with my code below.
I put these "remove" buttons ,cause when user add an item many times, a counter increases ,so when he uses this button this counter discreses.

Code:

from tkinter import *
from PIL import Image , ImageTk

root = Tk()
root.title("Super Market")
root.geometry("1500x1300")

food = [
        ("Rice" , 0.99) ,                       # value for radio_button -> 1
        ("Spaghetti" , 0.95) ,                  # value for radio_button -> 2
        ("Ice cream" , 3.44) ,                  # value for radio_button -> 3
        ("Pizza" , 7.50) ,                      # value for radio_button -> 4
        ("Cheese" , 2.10) ,                     # value for radio_button -> 5
        ("Cheddar" , 0.45) ,                    # value for radio_button -> 6
        ("Cherry" , 0.88) ,                     # value for radio_button -> 7
        ("Banana" , 0.40) ,                     # value for radio_button -> 8
        ("Apple" , 0.67) ,                      # value for radio_button -> 9
        ("Meat" , 7.28) ,                       # value for radio_button -> 10
        ("Fish" , 9.72) ,                       # value for radio_button -> 11
        ("Orange" , 0.62) ,                     # value for radio_button -> 12
        ("Orange juice" , 2.10) ,               # value for radio_button -> 13
        ("Chocolate" , 0.99) ,                  # value for radio_button -> 14
        ("Bread" , 0.55) ,                      # value for radio_button -> 15
        ("Milk" , 1.00)                         # value for radio_button -> 16
       ]

NUMBER_OF_FOODS = 16
food_name_var = StringVar()
food_name_var.set(-200)    # δεν δειχνει σε κανενα radio button αρχικα , αν εβαζα 1 θα εδειχνε στο 1ο προιον κοκ...

frame = LabelFrame(root , relief = SUNKEN , bd = 1)
frame.grid(row = 0 , column = 0 , sticky = W)

label_frame_food_info = LabelFrame(root , height = 600, width = 300 , relief = SUNKEN , bd = 2)
label_frame_food_info.place(x = 1200 , y = 50)

food_quantity = [0 for i in range(NUMBER_OF_FOODS)]

r = 0
y_lim_list = 0

for food_name , food_price in food:
        Radiobutton(frame , text = food_name , variable = food_name_var , value = r+1 , padx = 10 , pady = 5).grid(row = r , column = 0 , sticky = W)
        label_price = LabelFrame(root , relief = SUNKEN , bd = 1 , text = "Price")
        label_price.grid(row = r , column = 1 , sticky = W)
        r += 1
        

def select_food(food_name):
        global y_lim_list
        label_frame_food_info = LabelFrame(root , height = 600, width = 300 , relief = SUNKEN , bd = 2) # update shopping list
        label_frame_food_info.place(x = 1200 , y = 50)
        label_print_food = Label(label_frame_food_info , text = food_name + "    (" + str(food_quantity[int(food_name_var.get() ) - 1] + 1) + ")")
        food_quantity[int(food_name_var.get() ) - 1] += 1

        if(food_quantity[int(food_name_var.get() ) - 1] >= 1):
                button_remove_food = Button(label_frame_food_info , text = "Remove" , command = lambda: remove_selected_food(food[ int(food_name_var.get() ) - 1][0]))
                button_remove_food.grid(row = y_lim_list , column  = 1)
                
        label_print_food.grid(row = y_lim_list , column = 0)
        y_lim_list += 1
        


def remove_selected_food(item):
        return

lock_logo = Image.open("shopping_basket.jpg")
lock_logo = lock_logo.resize( (60 , 60) , resample = 0)
lock_image = ImageTk.PhotoImage(lock_logo)

button = Button(root , image = lock_image , command = lambda: select_food(food[ int(food_name_var.get() ) - 1][0]))
button.grid(row = 0 , column = 3 , sticky = S)


label_info = Label(root , text = "Shopping basket")
label_info.place(x = 1294 , y = 20)



root.mainloop()



RE: Python3 tkinter radiobutton problem - deanhystad - Feb-12-2021

A radio button group is not a good choice for this application. First you have to select an item, then you add it to the cart. Two clicks. Unless selecting an item brings up additional information to view before making a selection you should use a push button.

In the code below I make a button for each item in the inventory. Clicking the item adds it to the cart. The cart displays the item name and buttons to add more of the same, or to remove items.

There are likely widgets better than frame for displaying the cart, but this was easy and I am lazy.
import tkinter as tk

root = tk.Tk()
root.title("Super Market")
 
food = {
    "Rice": 0.99,
    "Spaghetti": 0.95,
    "Ice cream": 3.44,
    "Pizza": 7.50,
    "Cheese": 2.10, 
    "Cheddar": 0.45, 
    "Cherry": 0.88, 
    "Banana": 0.40, 
    "Apple": 0.67, 
    "Meat": 7.28, 
    "Fish": 9.72, 
    "Orange": 0.62, 
    "Orange juice": 2.10, 
    "Chocolate": 0.99, 
    "Bread": 0.55}

inventory = tk.Frame(root)
inventory.grid(row=0, column=0)

shopping_cart = {}

def update_cart():
    print(shopping_cart)
    for item in cart.winfo_children():
        item.grid_forget()
        item.destroy()

    for r, item in enumerate(shopping_cart):
        text = f'{shopping_cart[item]} x {item}'
        tk.Label(cart, text=text, width=20) \
            .grid(row=r, column=0)
        tk.Button(cart, text=' + ', command=lambda n=item: add_item(n)) \
            .grid(row=r, column=1)
        tk.Button(cart, text=' - ', command=lambda n=item: remove_item(n)) \
            .grid(row=r, column=2)

def add_item(item):
    shopping_cart[item] = shopping_cart.get(item, 0) + 1
    update_cart()

def remove_item(item):
    if item in shopping_cart:
        shopping_cart[item] -= 1
        if shopping_cart[item] <= 0:
            shopping_cart.pop(item)
        update_cart()

for item in food:
    button = tk.Button(inventory, text=item, width=20, command=lambda n=item: add_item(n))
    button.pack(side=tk.TOP)

cart = tk.Frame(root)
cart.grid(row=0, column=1)
  
root.mainloop()



RE: Python3 tkinter radiobutton problem - Nick_tkinter - Feb-12-2021

(Feb-12-2021, 08:21 PM)deanhystad Wrote: A radio button group is not a good choice for this application. You could just use buttons.
import tkinter as tk

root = tk.Tk()
root.title("Super Market")
 
food = {
    "Rice": 0.99,
    "Spaghetti": 0.95,
    "Ice cream": 3.44,
    "Pizza": 7.50,
    "Cheese": 2.10, 
    "Cheddar": 0.45, 
    "Cherry": 0.88, 
    "Banana": 0.40, 
    "Apple": 0.67, 
    "Meat": 7.28, 
    "Fish": 9.72, 
    "Orange": 0.62, 
    "Orange juice": 2.10, 
    "Chocolate": 0.99, 
    "Bread": 0.55}

inventory = tk.Frame(root)
inventory.grid(row=0, column=0)

shopping_cart = {}

def update_cart():
    print(shopping_cart)
    for item in cart.winfo_children():
        item.grid_forget()
        item.destroy()

    for r, item in enumerate(shopping_cart):
        text = f'{shopping_cart[item]} x {item}'
        tk.Label(cart, text=text, width=20) \
            .grid(row=r, column=0)
        tk.Button(cart, text=' + ', command=lambda n=item: add_item(n)) \
            .grid(row=r, column=1)
        tk.Button(cart, text=' - ', command=lambda n=item: remove_item(n)) \
            .grid(row=r, column=2)

def add_item(item):
    shopping_cart[item] = shopping_cart.get(item, 0) + 1
    update_cart()

def remove_item(item):
    if item in shopping_cart:
        shopping_cart[item] -= 1
        if shopping_cart[item] <= 0:
            shopping_cart.pop(item)
        update_cart()

for item in food:
    button = tk.Button(inventory, text=item, width=20, command=lambda n=item: add_item(n))
    button.pack(side=tk.TOP)

cart = tk.Frame(root)
cart.grid(row=0, column=1)
  
root.mainloop()
Is there any way to do it with radio buttons,because I want to do it that way.Thanks


RE: Python3 tkinter radiobutton problem - deanhystad - Feb-12-2021

I didn't say you couldn't do it that way, just that it is awkward. If you look at any GUI you like, you will see that radio buttons are use sparingly. If the number of choices grows above, say 5, a different widget is used.

Most applications with a large number of choices like this would use a list.

And don't use the replay button. It's not like we need a copy of my post for context.


RE: Python3 tkinter radiobutton problem - Nick_tkinter - Feb-12-2021

So,you tell me it's not a good idea to use radio buttons if I have many choices.Ok.I will remember this.Thanks.I will do it with buttons. Smile


RE: Python3 tkinter radiobutton problem - Nick_tkinter - Feb-12-2021

My problem is how can I put a label and a button inside a frame.Do you know how can I do this?


RE: Python3 tkinter radiobutton problem - deanhystad - Feb-12-2021

I provided an example. Didn't you try it?