For study reasons, as the title suggests, I would like to recall the functions by selecting the items in a combobox.
For example, if I select Item1
in the combobox, I would like to call function_item1()
and then display This is function: function_item1
inside the textbox. The same if I select functions 2 and 3.
What can I do? Currently, of course, I get:
This is function: None
NOTE: I have not changed my code too much, I would like the logical structure to remain almost this
from tkinter import ttk
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.geometry("400x150")
combobox=ttk.Combobox(root, width = 18)
combobox.place(x=15, y=15)
combobox['value'] = ["Item 1", "Item 2", "Item 3"]
combobox.set("Select")
textbox = tk.Text(root,width=43,height=2)
textbox.place(x=15, y=50)
def all_function():
a = b = c = None
#function 1
if combobox.get() == "Item 1":
def function_item1():
a = "function_item1"
#function 2
if combobox.get() == "Item 2":
def function_item2():
b = "function_item2"
#function 3
if combobox.get() == "Item 3":
def function_item3():
c = "function_item3"
#PRINT FUNCTIONS
def print():
text = f"This is function: {a or b or c}"
textbox.insert(tk.END, text)
print()
button2 = Button(root, text="Print", command = all_function)
button2.pack()
button2.place(x=15, y=100)
CodePudding user response:
An easy way is not to create alot of functions and pollute the namespace, rather just create the required functions and put it all inside a main function. This way you will avoid the extra function print
, that you just defined.
Method 1:
def function_item1():
return "function_item1"
def function_item2():
return "function_item2"
def function_item3():
return "function_item3"
def all_function():
if combobox.get() == 'Item 1':
text = function_item1()
elif combobox.get() == 'Item 2':
text = function_item2()
else:
text = function_item3()
textbox.insert('end',text)
Method 2: But a more professional way is to not create functions for these simple stuff like just assigning value to a piece of string that you want to use later, rather you can just avoid functions itself.
def all_function():
if combobox.get() == 'Item 1':
text = "function_item1"
elif combobox.get() == 'Item 2':
text = "function_item2"
else:
text = "function_item3"
textbox.insert('end',text)
Method 3: Another way is to use a dictionary to store the value for the each item in combobox:
def all_function():
mapper = {
'Item 1': "function_item1",
'Item 2': "function_item2",
'Item 3': "function_item3",
}
text = mapper.get(combobox.get(), 'None')
textbox.insert('end',text)
And of course this can also be used in conjecture with having different function. This case is if you have to have to do something more than just returning a piece of text.
def function_item1():
# Any big stuff you want to process on the text to be returned
return "function_item1"
def function_item2():
return "function_item2"
def function_item3():
return "function_item3"
def all_function():
mapper = {
'Item 1': function_item1(),
'Item 2': function_item2(),
'Item 3': function_item3(),
}
text = mapper.get(combobox.get(), 'None')
textbox.insert('end',text)
Though note, if you want to execute a function that will do certain activity, then you should remove the ()
to not call the function while the dictionary is made itself.
There are many reasons why your code did not work:
- The first reason is that, you are creating functions but you are not executing them.
- The next being, even if you execute the function, you will also have to globalize the variable because the functions are nested functions and
a
orb
orc
is not expected to be used outside their respective function. - Now even if you globalize
a
,b
andc
, still it will beNone
insideprint
becausea
,b
, andc
used inside the scope ofprint
will be the local one created(which isNone
), so you will have to let it know to use the global one withglobal a,b,c
OR you will have to movea = b = c = None
to outside the function and then you can avoid sayingglobal a
insideprint
. - Then after that, saying
a or b or c
is wrong, as it will evaluate the expression and return aTrue
orFalse
. So if you want to show either of the 3 texts when an item is selected, you will have to name everything into a same variable name instead ofa,b,c
liketext
and insert that. - Also don't overwrite inbuilt function names like
print
, with your own version, name it something different.
So because of these reasons, we have to change your structure to make it usable. But if you want to see the working version of your code, which I would recommend not to use, is:
text = None # Solution to reason 3 and 4
def all_function():
#function 1
if combobox.get() == "Item 1":
def function_item1():
global text # Solution to reason 2
text = "function_item1"
function_item1() # Solution to reason 1
#function 2
if combobox.get() == "Item 2":
def function_item2():
global text
text = "function_item2"
function_item2()
#function 3
if combobox.get() == "Item 3":
def function_item3():
global text
text = "function_item3"
function_item3()
#PRINT FUNCTIONS
def show(): # Solution to reason 5
final_text = f"This is function: {text}" # Solution to reason 4
textbox.insert(tk.END, final_text)
show()