简体   繁体   中英

Python tkinter: create a dynamic dropdown menu and call different actions after selection

I am pretty new to python and this is the first time I use tkinter so I hope someone can help me to find the right direction.

Basically this is what I would like to achieve:

  1. I retrieve from an XML 2 lists (APPs, IDs);
  2. The APP List will be shown in a Dropdown menu;
  3. The APP selection in the Dropdown menu will call the APP status using its ID.

I can't get the last point work, basically I think I understand why (I have no matching between the two lists or a function to match them, and the selection calls automatically the last ID of second list) but I am to the best of my knowledge not able to solve it.

import requests
import xml.etree.ElementTree as ET

import tkinter as tk

APP_OPTIONS = []
ID_OPTIONS = []

session = requests.Session()
session.auth = ('USER', 'PW')
applications = session.get('https://getapplicationslist.myurl.com/application/')
applications_xml = applications.content
root = ET.fromstring(applications_xml)
for application in root.findall('application'):
    app_name = application.find('name').text
    app_id = application.find('id').text
    APP_OPTIONS.append(app_name)
    ID_OPTIONS.append(app_id)

def appcall(*args):
    app_status = session.get('https://getapplicationstatus.myurl.com?Id=' + app_id)
    status_xml = app_status.content
    root = ET.fromstring(status_xml)
    for appStatus in root.findall('appStatus'):
        status = appStatus.find('status').text
        print(status)

root = tk.Tk()
root.title('Application List')
root.geometry("300x200")

var =tk.StringVar(root)
var.set('Choose an Application')
var.trace('w', appcall)

dropDownMenu = tk.OptionMenu(root, var, *APP_OPTIONS)
dropDownMenu.pack()

root.mainloop()
print('End Request')

As mentioned in my comment, the issue is your app_id in appcall does not change. You need to get the corresponding ID from the ID_OPTIONS instead.

def appcall(*args):
    app_id = ID_OPTIONS[APP_OPTIONS.index(var.get())]  # Add this line
    app_status = session.get('https://getapplicationstatus.myurl.com?Id=' + app_id)
    ...

The app_id is now set to the ID_OPTIONS of the same index based on the app_name (since the insertion order is the same).

However , a better approach would be to initialize your options as a dictionary instead:

# instead of APP_OPTIONS / ID_OPTIONS, create:
apps = {}

...

for application in root.findall('application'):
    app_name = application.find('name').text
    app_id = application.find('id').text
    # add to dictionary here:
    apps[app_name] = app_id

def appcall(*args):
    # Change the app_id to apps.get(var.get())
    app_status = session.get('https://getapplicationstatus.myurl.com?Id=' + apps.get(var.get())
    ...

See how much simpler it is to recall the same reference?

If you are feeling comfortable about the language, you might even opt for a dictionary comprehension:

...
root = ET.fromstring(applications_xml)
app_id = {application.find('name').text: application.find('id').text for application in root.findall('application')}
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM