2

For my first real project I'm using Tkinter to create a UI where, when a button is pressed, something happens.

I've created the UI which works well - buttons are made and are clickable, but I want each button to have it's own unique function - this is where I get lost.

I've got a nested dictionary:

siteDict = {1: {'app1': 'explorer', 'app2': 'firefox', 'app3': 'google-chrome', 'app4': 'edge'},
            2: {'site1': 'http://www.google.com', 'site2': 'http://www.yahoo.com', 'site3': 'http://altavista', 'site4': 'http://www.askjeeves.com', }}

And I want to pass entries from the dictionary to terminal instead of having to manually define each one like I am now:

def Expl_Goog():
        os.system('echo Opening Explorer and navigating to Google (http://www.google.com). Please wait.')

So instead of doing echo Opening Explorer and navigating to Google (http://www.google.com). Please wait. is there a way to pass 2 items from my dictionary into the terminal command? {app1} and {site1} in this example.

Defining variables for ~12 things isn't terrible, but the real side of the project has the same type of dictionary but with 64 entries in each one.

Here's the code I have so far, which is functional. The button click functionality is done via the "command" argument within the button creation - ttk.Button(self.Explorer_labelFrame, text="google", command=Expl_Goog).grid(column=0, row=0, pady=2, sticky=tk.EW)

Built on 3.9.5

import tkinter as tk
from tkinter import ttk
import os

# Dictionary to house variables
siteDict = {1: {'app1': 'explorer', 'app2': 'firefox', 'app3': 'google-chrome', 'app4': 'edge'},
            2: {'site1': 'http://www.google.com', 'site2': 'http://www.yahoo.com', 'site3': 'http://altavista', 'site4': 'http://www.askjeeves.com', }}

# Defining the action for the Tkinter button press to do
def Expl_Goog():
        os.system('echo Opening Explorer and navigating to Google (http://www.google.com). Please wait.')

# Another definition - Explorer and Yahoo
def Expl_Yah():
        os.system('echo Opening Explorer and navigating to Yahoo (http://www.yahoo.com). Please wait.')

def Fire_Goog():
        os.system('echo Opening Firefox and navigating to Google (http://www.google.com). Please wait.')

def Fire_Yah():
    os.system('echo Opening Firefox and navigating to Yahoo (http://www.yahoo.com). Please wait.')

# Build UI via Tkinter
class App(tk.Tk):
    def __init__(self):
        super(App, self).__init__()

        self.title("Website Launcher")
        self.minsize(200, 400)
        #self.wm_iconbitmap('icon.ico')
        self.lift()
        self.attributes('-topmost', True)
        self.update()

        self.Explorer_labelFrame = ttk.LabelFrame(self, text="Explorer", labelanchor='n')
        self.Explorer_labelFrame.grid(column=0, row=7, padx=20, pady=40)
        
        self.Firefox_labelFrame = ttk.LabelFrame(self, text="Firefox", labelanchor='n')
        self.Firefox_labelFrame.grid(column=2, row=7, padx=20, pady=40)


        self.labels_Explorer()
        self.labels_Firefox()

# Creating UI Buttons
# "command" argument makes clicking the button run the terminal command defined above
    def labels_Explorer(self):
        ttk.Button(self.Explorer_labelFrame, text="google", command=Expl_Goog).grid(column=0, row=0, pady=2, sticky=tk.EW)
        ttk.Button(self.Explorer_labelFrame, text="yahoo", command=Expl_Yah).grid(column=0, row=1, pady=2, sticky=tk.EW)
        ttk.Button(self.Explorer_labelFrame, text="altavista").grid(column=0, row=2, pady=2, sticky=tk.EW)
        ttk.Button(self.Explorer_labelFrame, text="askjeeves").grid(column=0, row=3, pady=2, sticky=tk.EW)

    def labels_Firefox(self):
        ttk.Button(self.Firefox_labelFrame, text="google", command=Fire_Goog).grid(column=0, row=0, pady=2, sticky=tk.EW)
        ttk.Button(self.Firefox_labelFrame, text="yahoo", command=Fire_Yah).grid(column=0, row=1, pady=2, sticky=tk.EW)
        ttk.Button(self.Firefox_labelFrame, text="altavista").grid(column=0, row=2, pady=2, sticky=tk.EW)
        ttk.Button(self.Firefox_labelFrame, text="askjeeves").grid(column=0, row=3, pady=2, sticky=tk.EW)

app = App()
app.mainloop()

1 Answer 1

1

If I understand you right, you want to do a product between apps and sites:

from itertools import product

siteDict = {
    1: {
        "app1": "explorer",
        "app2": "firefox",
        "app3": "google-chrome",
        "app4": "edge",
    },
    2: {
        "site1": "http://www.google.com",
        "site2": "http://www.yahoo.com",
        "site3": "http://altavista",
        "site4": "http://www.askjeeves.com",
    },
}


for app, site in product(siteDict[1].values(), siteDict[2].values()):
    s = "echo Opening {app} and navigating to {site}. Please wait.".format(
        app=app, site=site
    )
    print(s)

Prints:

echo Opening explorer and navigating to http://www.google.com. Please wait.
echo Opening explorer and navigating to http://www.yahoo.com. Please wait.
echo Opening explorer and navigating to http://altavista. Please wait.
echo Opening explorer and navigating to http://www.askjeeves.com. Please wait.
echo Opening firefox and navigating to http://www.google.com. Please wait.
echo Opening firefox and navigating to http://www.yahoo.com. Please wait.
echo Opening firefox and navigating to http://altavista. Please wait.
echo Opening firefox and navigating to http://www.askjeeves.com. Please wait.
echo Opening google-chrome and navigating to http://www.google.com. Please wait.
echo Opening google-chrome and navigating to http://www.yahoo.com. Please wait.
echo Opening google-chrome and navigating to http://altavista. Please wait.
echo Opening google-chrome and navigating to http://www.askjeeves.com. Please wait.
echo Opening edge and navigating to http://www.google.com. Please wait.
echo Opening edge and navigating to http://www.yahoo.com. Please wait.
echo Opening edge and navigating to http://altavista. Please wait.
echo Opening edge and navigating to http://www.askjeeves.com. Please wait.

EDIT: To get only specific combination:

siteDict = {
    1: {
        "app1": "explorer",
        "app2": "firefox",
        "app3": "google-chrome",
        "app4": "edge",
    },
    2: {
        "site1": "http://www.google.com",
        "site2": "http://www.yahoo.com",
        "site3": "http://altavista",
        "site4": "http://www.askjeeves.com",
    },
}


def get(a, b):
    s = "echo Opening {app} and navigating to {site}. Please wait."
    return s.format(
        app=siteDict[1]["app{}".format(a)], site=siteDict[2]["site{}".format(b)]
    )


print(get(1, 3))

Prints:

echo Opening explorer and navigating to http://altavista. Please wait.
Sign up to request clarification or add additional context in comments.

3 Comments

Hey thanks for this! So this does well to print every permutation but how would I incorporate it in regards to getting it to reference just the single variable? print(s) does everything but the problem I'm running in to is that I want to have a function that can be called with parameters where the specified parameters is an item from the dictionary. So in the "command" parameter of the button I can just do something like command=web(1,3) where web is the function and 1=first dict first entry, 3=2nd dict 3rd entry (or something like that). Basically 1 button = 1 action that includes vars
Perfect, that's exactly what I was looking for. Would you mind pointing me in a direction on what to research for what I always asking for? Is this mostly just knowing how .format comes into play? I'm relatively new to Python and trying to learn what I can when I use it. Thanks again @andrej.
@Feanux Look at official documentation of str.format. Or w3schools.com/python/ref_string_format.asp is a good resource.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.