Home > Enterprise >  Call different functions with multiple choice of items in a combobox, and print text in textbox
Call different functions with multiple choice of items in a combobox, and print text in textbox

Time:07-09

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:

  1. The first reason is that, you are creating functions but you are not executing them.
  2. 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 or b or c is not expected to be used outside their respective function.
  3. Now even if you globalize a,b and c, still it will be None inside print because a,b, and c used inside the scope of print will be the local one created(which is None), so you will have to let it know to use the global one with global a,b,c OR you will have to move a = b = c = None to outside the function and then you can avoid saying global a inside print.
  4. Then after that, saying a or b or c is wrong, as it will evaluate the expression and return a True or False. 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 of a,b,c like text and insert that.
  5. 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()
  • Related