Radiobutton choices auto-filled before selection

  • Context: Python 
  • Thread starter Thread starter Eclair_de_XII
  • Start date Start date
  • Tags Tags
    Choices
Click For Summary

Discussion Overview

The discussion revolves around the use of tkinter's Radiobuttons and the behavior of the associated variable types, specifically BooleanVar and StringVar. Participants explore issues related to auto-filling of Radiobuttons and the implications of using different variable types for managing user selections.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant notes that using a BooleanVar leads to the side_dish attribute evaluating to False even when set to None, and suggests trying a StringVar instead.
  • Another participant points out that None is not a boolean value in Python, which explains why it evaluates to False when passed to a BooleanVar.
  • There is a suggestion that radio buttons are typically expected to map to zero-based integer values, which prompts a participant to consider this in their solution.
  • A participant proposes initializing side_dish as an IntVar with a default value of -1 to accommodate multiple choices, although they clarify their specific use case only requires two options.

Areas of Agreement / Disagreement

Participants express differing views on the appropriateness of using BooleanVar for Radiobuttons, with some advocating for alternative approaches while others defend the initial choice. The discussion remains unresolved regarding the best practices for variable types in this context.

Contextual Notes

There are limitations related to the assumptions about variable types and their behavior in tkinter, as well as the implications of using None with BooleanVar. The discussion does not resolve these complexities.

Eclair_de_XII
Messages
1,082
Reaction score
91
TL;DR
I'm trying to create a frame of Radiobutton widgets, but for some odd reason, the widgets are already filled before the user even selects them. I've tried tinkering with the type of the variable linked to the widgets, but the problem still persists.
Whenever I use a BooleanVar, the side_dish attribute keeps evaluating to False even if I set it to None. So I tried setting it to a StringVar. This time, both the Radiobutton seem to be auto-filled, even though nothing is even selected. If anyone could shed some light on why this happens, I would very much appreciate it. I am not sure if tkinter is still commonly used, but I am intent on sticking to it, either way.

Python:
from tkinter import *

class Restaurant:
    def __init__(self):
        self.side_dish=None
        self.root=Tk()
        self.root.title('Waiter')
        self.mainFrame=Frame(self.root)
        self.mainFrame.grid()

    def endProcess(self,*args):
        self.root.destroy()

    def initializeParams(self,varType):
        if varType == 'str':
            self.side_dish=StringVar()
            self.soupVal='Soup'
            self.saladVal='Salad'
        elif varType == 'bool':
            self.side_dish=BooleanVar()
            self.soupVal=False
            self.saladVal=True

    def chooseSide(self):
        question='Would you like the salad or the soup?'
        #   To create white-space so that title shows
        question+=' '*5
        Label(self.mainFrame,text=question).grid(row=0,columnspan=2)

        d={}
        d['varType']='bool'

        self.initializeParams(**d)

        kw={
            'master':self.mainFrame,\
            'variable':self.side_dish,\
            'command':self.printSelection
            }

        soupButton=Radiobutton(text='Soup',value=self.soupVal,**kw)
        saladButton=Radiobutton(text='Salad',value=self.saladVal,**kw)

        buttonPos={
            'column':0,\
            'sticky':W
            }

        soupButton.grid(row=1,**buttonPos)
        saladButton.grid(row=2,**buttonPos)

        soupButton.focus()

    def printSelection(self,*args):
        chose_salad=self.side_dish.get()
        kw={
            'master':self.mainFrame
            }
        Label(text='User chose salad:',**kw).grid(row=1,column=1)
        Label(text='%s'%chose_salad,**kw).grid(row=2,column=1)

        self.root.bind_all('<Return>',self.endProcess)

    def __call__(self):
        self.root.bind_all('<Escape>',self.endProcess)
        self.chooseSide()

if __name__ == '__main__':
    Restaurant()()
 
Technology news on Phys.org
Boolean is a bad choice for radio buttons - what happens when you want to add another choice? If you want this to be a boolean value then use a checkbox.

Although you initially set side_dish to None you override it in initializeParams to a tk.StringVar. I am not an expert on tkinter but you could try self.side_dish.set('') after line 16.
 
Eclair_de_XII said:
Whenever I use a BooleanVar, the side_dish attribute keeps evaluating to False even if I set it to None.

Of course, because None is not a boolean value in Python; only False and True are. Whenever you hand an object to a BooleanVar, it converts it to a Python boolean value (using the built-in function bool, AFAIK, which evaluates to False if called with None as its argument).

Eclair_de_XII said:
So I tried setting it to a StringVar.

Normally, AFAIK, radio buttons are expected to map to zero-based integer values.
 
PeterDonis said:
zero-based integer values

It baffles me how simple the solution I came up with was, based on this remark alone. Thanks.

[CODE lang="python" highlight="23-26,35"]from tkinter import *

class Restaurant:
def __init__(self):
self.side_dish=None
self.root=Tk()
self.root.title('Waiter')
self.mainFrame=Frame(self.root)
self.mainFrame.grid()

def endProcess(self,*args):
self.root.destroy()

def initializeParams(self,varType):
if varType == 'str':
self.side_dish=StringVar()
self.soupVal='Soup'
self.saladVal='Salad'
elif varType == 'bool':
self.side_dish=BooleanVar()
self.soupVal=False
self.saladVal=True
elif varType == 'int':
self.side_dish=IntVar(value=-1)
self.saladVal=1
self.soupVal=0

def chooseSide(self):
question='Would you like the salad or the soup?'
# To create white-space so that title shows
question+=' '*5
Label(self.mainFrame,text=question).grid(row=0,columnspan=2)

d={}
d['varType']='int'

self.initializeParams(**d)

kw={
'master':self.mainFrame,\
'variable':self.side_dish,\
'command':self.printSelection
}

soupButton=Radiobutton(text='Soup',value=self.soupVal,**kw)
saladButton=Radiobutton(text='Salad',value=self.saladVal,**kw)

buttonPos={
'column':0,\
'sticky':W
}

soupButton.grid(row=1,**buttonPos)
saladButton.grid(row=2,**buttonPos)

soupButton.focus()

def printSelection(self,*args):
chose_salad=self.side_dish.get()
kw={
'master':self.mainFrame
}
Label(text='User chose salad:',**kw).grid(row=1,column=1)
Label(text='%s'%chose_salad,**kw).grid(row=2,column=1)

self.root.bind_all('<Return>',self.endProcess)

def __call__(self):
self.root.bind_all('<Escape>',self.endProcess)
self.chooseSide()

if __name__ == '__main__':
Restaurant()()
[/CODE]

pbuk said:
what happens when you want to add another choice

In my case, I only have the user choose from two options.
 
Last edited:

Similar threads

  • · Replies 4 ·
Replies
4
Views
2K