这个问题在这里已经有答案:
How to check if all elements of a list match a condition?(5个答案)
两小时前就关门了。
目前正在开发一款F1 Tkinter gui应用程序,该应用程序允许用户输入司机(通过键入或从列表框中选择司机),并显示相关统计数据。
目前,我正在尝试这样做:当用户输入与drivers_list
中的条目不匹配时,列表框menu
应该显示一个字符串“No Item Found”(或者更好的是,当前的USER_INPUT+“Not Found”)
我试过几种不同的方法。例如,在下面显示的代码中,我在check
中放置了一个单独的Else-语句,其中输出了“No Item Found”,但结果是,menu
中只显示了1个“No Item Found”,而是显示了多个。我想我知道为什么会显示多个,但我不知道解决方案。看起来问题确实出在check
上,但我可能错了
以下是该问题的图片
代码如下:
# UI Design approach 4
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
from tkinter import messagebox
import requests
import json
root = Tk()
root.geometry("800x300")
root.title("F1 Desktop Application")
root.iconbitmap("formula1_logo.ico")
# generate 2022 drivers-list [can scale to drivers-list by changing the]
drivers_list_request = requests.get("http://ergast.com/api/f1/2022/drivers.json")
# initialize empty-list
drivers_list = []
drivers_list_object = json.loads(drivers_list_request.content)
for elements in drivers_list_object["MRData"]["DriverTable"]["Drivers"]:
drivers_list.append(elements["givenName"] + " " + elements["familyName"])
# Update the Entry widget with the selected item in list
def check(e):
v= entry_box.get()
if v=='':
hide_button(menu)
else:
data=[]
for item in drivers_list:
if v.lower() in item.lower():
data.append(item)
else:
data.append("Item not Found")
update(data)
show_button(menu)
def update(data):
# Clear the Combobox
menu.delete(0, END)
# Add values to the combobox
for value in data:
menu.insert(END,value)
def fillout(event):
try:
entry_box.delete(0,END)
entry_box.insert(0,menu.get(menu.curselection()))
hide_button(menu)
#handle a complete deletion of entry-box via cursor double tap
except:
pass
def hide_button(widget):
widget.grid_remove()
def show_button(widget):
widget.grid()
def full_name():
lower_user_input = grab_user_input()
response = requests.get("http://ergast.com/api/f1/drivers/{}.json".format(lower_user_input))
response_object = json.loads(response.content)
name = response_object["MRData"]["DriverTable"]["Drivers"][0]["givenName"] + " " + response_object["MRData"]["DriverTable"]["Drivers"][0]["familyName"]
driver_name_label.configure(text = name)
def team():
lower_user_input = grab_user_input()
response = requests.get("http://ergast.com/api/f1/current/drivers/{}/constructors.json".format(lower_user_input))
response_object = json.loads(response.content)
team = response_object["MRData"]["ConstructorTable"]["Constructors"][0]["name"]
team_api.configure(text = team)
def driver_code():
lower_user_input = grab_user_input()
response = requests.get("http://ergast.com/api/f1/drivers/{}.json".format(lower_user_input))
response_object = json.loads(response.content)
code = response_object["MRData"]["DriverTable"]["Drivers"][0]["code"]
code_api.configure(text = code)
def nationality():
lower_user_input = grab_user_input()
response = requests.get("http://ergast.com/api/f1/drivers/{}.json".format(lower_user_input))
response_object = json.loads(response.content)
nationality = response_object["MRData"]["DriverTable"]["Drivers"][0]["nationality"]
nationality_api.configure(text = nationality)
def wins():
lower_user_input = grab_user_input()
response = requests.get("http://ergast.com/api/f1/drivers/{}/results/1.json".format(lower_user_input))
response_object = json.loads(response.content)
wins = response_object["MRData"]["total"]
wins_api.configure(text = wins)
def poles():
lower_user_input = grab_user_input()
response = requests.get("http://ergast.com/api/f1/drivers/{}/qualifying/1.json".format(lower_user_input))
response_object = json.loads(response.content)
poles = response_object["MRData"]["total"]
poles_api.configure(text = poles)
def podiums():
lower_user_input = grab_user_input()
#podiums is sum of 1st, 2nd, 3rd place finishes
#####DRY principle; let's reuse the code from wins()
######noticing how maybe should create a separate function which "places" the widget
#######for now, reuse the code
#1st place finishes
response = requests.get("http://ergast.com/api/f1/drivers/{}/results/1.json".format(lower_user_input))
response_object = json.loads(response.content)
#convert wins to int
wins = int(response_object["MRData"]["total"])
#2nd place finishes
response_ii = requests.get("http://ergast.com/api/f1/drivers/{}/results/2.json".format(lower_user_input))
response_ii_object = json.loads(response_ii.content)
response_ii_amount = int(response_ii_object["MRData"]["total"])
#3rd place finishes
response_iii = requests.get("http://ergast.com/api/f1/drivers/{}/results/3.json".format(lower_user_input))
response_iii_object = json.loads(response_iii.content)
response_iii_amount = int(response_iii_object["MRData"]["total"])
podiums = str(wins + response_ii_amount + response_iii_amount)
podiums_api.configure(text = podiums)
def championships():
lower_user_input = grab_user_input()
response = requests.get("http://ergast.com/api/f1/drivers/{}/driverStandings/1/seasons.json".format(lower_user_input))
response_object = json.loads(response.content)
championships = response_object["MRData"]["total"]
championships_api.configure(text = championships)
def standing():
lower_user_input = grab_user_input()
response = requests.get("http://ergast.com/api/f1/current/drivers/{}/driverStandings.json".format(lower_user_input))
response_object = json.loads(response.content)
position = response_object["MRData"]["StandingsTable"]["StandingsLists"][0]["DriverStandings"][0]["position"]
points = response_object["MRData"]["StandingsTable"]["StandingsLists"][0]["DriverStandings"][0]["points"]
standing = "{} ({} pts)".format(position, points)
standing_api.configure(text = standing)
def grab_user_input():
#need to find a scalable way, since what if this was an app to search any driver in history?
edge_case_inputs = ["Max Verstappen", "Kevin Magnussen", "Mick Schumacher"]
user_input = entry_box.get()
if user_input in edge_case_inputs:
lower_user_input = user_input.lower().replace(" ", "_")
return lower_user_input
#very unique case which can't be modularsed
elif user_input == "Nyck de Vries":
lower_user_input = "de_vries"
else:
lower_user_input = user_input.lower().split(" ")[1]
return lower_user_input
def search():
#slow run-time is simply due to the multiple api calls made
hide_button(menu)
#fast-run time
full_name()
#fast-run time
team()
#fast-run time
driver_code()
#fast-run time
nationality()
#fast-run time
wins()
#fast-run time
poles()
#fast-run time
podiums()
#fast-run time
championships()
#fast-run time
standing()
show_button(main_frame)
left_frame = LabelFrame(root, width = 275, height = 300)
left_frame.grid(row = 1, column = 0, sticky = SE)
left_frame.grid_propagate(False)
search_label = Label(left_frame, text = "Search Driver", font = ("Arial bold", 12))
search_label.grid(row = 0, column = 0, pady = 10)
entry_box = Entry(left_frame, bd = 5)
entry_box.grid(row = 1, column = 0, padx = 35, pady = 40)
entry_box.bind('<KeyRelease>',check)
# pass something into the lamda
search_button = Button(left_frame, text = "search", command = search)
search_button.grid(row = 1, column = 1, padx = 15)
menu= Listbox(left_frame, height = 7)
menu.grid(row = 2, column = 0)
menu.bind("<<ListboxSelect>>",fillout)
main_frame = LabelFrame(root, width = 575, height = 300)
main_frame.grid(row = 1, column = 1, sticky = SE)
main_frame.grid_propagate(False)
driver_name_label = Label(main_frame, text = "", font = ("Arial", 15))
driver_name_label.grid(row = 0, column = 0,pady = 30)
team_label = Label(main_frame, text = "TEAM", font = ("Arial", 10))
team_label.grid(row = 1, column = 0, sticky = W)
team_api = Label(main_frame, text = "", font = ("Arial", 10))
team_api.grid(row = 1, column = 1)
nationality_label = Label(main_frame, text = "NATIONALITY", font = ("Arial", 10))
nationality_label.grid(row = 2, column = 0, sticky = W)
nationality_api = Label(main_frame, text = "", font = ("Arial", 10))
nationality_api.grid(row = 2, column = 1, sticky = W)
driver_code_label = Label(main_frame, text = "DRIVER CODE", font = ("Arial", 10))
driver_code_label.grid(row = 3, column = 0, sticky = W)
code_api = Label(main_frame, text = "", font = ("Arial", 10))
code_api.grid(row = 3, column = 1, sticky = W)
wins_label = Label(main_frame, text = "WINS", font = ("Arial", 10))
wins_label.grid(row = 4, column = 0, sticky = W)
wins_api = Label(main_frame, text = "", font = ("Arial", 10))
wins_api.grid(row = 4, column = 1, sticky = W)
podiums_label = Label(main_frame, text = "PODIUMS", font = ("Arial", 10))
podiums_label.grid(row = 1, column = 2, sticky = W, padx = 15)
podiums_api = Label(main_frame, text = "", font = ("Arial", 10))
podiums_api.grid(row = 1, column = 3, padx = 15, sticky = W)
poles_label = Label(main_frame, text = "POLES", font = ("Arial", 10))
poles_label.grid(row = 2, column = 2, sticky = W, padx = 15)
poles_api = Label(main_frame, text = "", font = ("Arial", 10))
poles_api.grid(row = 2, column = 3, sticky = W, padx = 15)
world_championships_label = Label(main_frame, text = "WORLD CHAMPIONSHIPS", font = ("Arial", 10))
world_championships_label.grid(row = 3, column = 2, padx = 15, sticky = W)
championships_api = Label(main_frame, text = "", font = ("Arial", 10))
championships_api.grid(row = 3, column = 3, padx = 15, sticky = W)
current_standing_label = Label(main_frame, text = "F1 2022 STANDING", font = ("Arial", 10))
current_standing_label.grid(row = 4, column = 2, padx = 15, sticky = W)
standing_api = Label(main_frame, text = "", font = ("Arial", 10))
standing_api.grid(row = 4, column = 3, padx = 15, sticky = W)
hide_button(menu)
hide_button(main_frame)
root.mainloop()
如果任何人有后续问题需要澄清,请让我知道!
谢谢,萨夫万
1条答案
按热度按时间5q4ezhmt1#
Instead of adding "Item not found" to
data
in every iteration of the loop, don't add it until after the loop, ifdata
is empty.