Python 3.x 如何确保某些类和函数调用可以访问所有GUI输入变量?
当我向输入栏提供地址和/或位置并按下“获取预测”按钮时,脚本在第22行失败。我认为引发此错误是因为str(address.get())找不到address变量,可能是因为在运行时这一点上它在技术上不存在(由于该函数的结构,我无法记录此错误) 我的问题是;如何确保“获取每小时预测”功能能够访问地址输入变量? 我尝试在不同的位置实例化address变量,例如在MainWeatherHub类和MyWeatherApp类中,然后将其作为参数传递给第79行的MainWeatherHub,但这两种变体都不起作用。当前代码显示前一个变化Python 3.x 如何确保某些类和函数调用可以访问所有GUI输入变量?,python-3.x,oop,tkinter,Python 3.x,Oop,Tkinter,当我向输入栏提供地址和/或位置并按下“获取预测”按钮时,脚本在第22行失败。我认为引发此错误是因为str(address.get())找不到address变量,可能是因为在运行时这一点上它在技术上不存在(由于该函数的结构,我无法记录此错误) 我的问题是;如何确保“获取每小时预测”功能能够访问地址输入变量? 我尝试在不同的位置实例化address变量,例如在MainWeatherHub类和MyWeatherApp类中,然后将其作为参数传递给第79行的MainWeatherHub,但这两种变体都不起
import urllib, json, requests
from tkinter import *
from tkinter import ttk
def get_hourly_forecast(*args):
#@ params *args:
#A location argument
#Returns:
# A list of temps in Farenheit for the next 156 hours
API_KEY = 'removing my API key for security purposes'
try:
print('here') # The code makes it to here
curr_address = str(address.get()) # Code seems to fail here (not sure how to have the error print)
print('here')
geocode_url = "https://maps.googleapis.com/maps/api/geocode/json?address={}&key={}".format(cur_address, API_KEY)
response = requests.get(geocode_url)
response_dict = response.json()['results']
location = response_dict[0]['geometry']['location']
lat = location['lat']
lng = location['lng']
local_url_request = 'https://api.weather.gov/points/lat={}lng={}'.format(lat, lng)
response_one = requests.get(local_url_request)
json_dict_one = response_one.json()
local_props = json_dict_one['properties']
local_forecast_request = local_props['forecastHourly']
resposne_two = requests.get(local_forecast_request)
json_dict_two = resposne_two.json()
local_forecast_properites = json_dict_two['properties']
hourly_updates = local_forecast_properites['periods']
out = []
for i in hourly_updates:
for key, value in i.items():
if key == "temperature":
out.append(value)
current_weather.set(out[0])
except:
print("Not working.")
#############################################################
class MyWeatherApp:
"""
MyWeatherApp is the primary Frame for this GUI application
"""
def __init__(self, master):
super(MyWeatherApp, self).__init__()
self.master = master
# Create the main window Frame
master_style = ttk.Style()
master_style.configure('Master.TFrame')
self.master.title("My Weather")
self.master.geometry("500x500")
MWA = ttk.Frame(self.master, style='Master.TFrame')
MWA.place(relheight=1.0, relwidth=1.0)
# Run other widgets within this class
MainWeatherHub(MWA)
#############################################################
class MainWeatherHub(MyWeatherApp):
"""
The MainWeatherHub (MWH) is the top panel of the app
"""
def __init__(self, mainwindow):
super(MyWeatherApp, self).__init__()
self.mainwindow = mainwindow
# Create a Frame for the MainWeatherHub
MWH_style = ttk.Style()
MWH_style.configure('MWH.TFrame')
MWH = ttk.Frame(self.mainwindow, style='MWH.TFrame', relief='sunken')
MWH.place(relheight=0.33, relwidth=0.95, relx=0.025, rely=0.025)
# Create an entry widget to take a location
# and store that as a loction variable.
address = StringVar()
loc_entry = ttk.Entry(MWH, textvariable=address)
loc_entry.place(relheight=0.30, relwidth=.95, relx=0.025, rely=0.05)
# Get weather button finds weather for the users location
current_weather = StringVar()
get_weather_button = ttk.Button(loc_entry, text="Get Forecast", command=get_hourly_forecast)
get_weather_button.place(relheight=0.85,relwidth=0.2, relx=0.79, rely=0.075)
#Display weather in the Message widget
weath_display = Message(MWH, textvariable=current_weather)
weath_display.place(relwidth=0.95, relheight=0.55, relx=0.025, rely=0.375)
root = Tk()
my_gui = MyWeatherApp(root)
root.mainloop()
如果此脚本工作正常,它应返回输入栏中提供位置的当前温度(以华氏度为单位)。您应将其作为参数发送
def get_hourly_forecast(cur_address):
geocode_url = "...".format(cur_address, API_KEY)
然后,使用按钮函数,该函数使用字符串运行get\u hourly\u forecast
class MainWeatherHub(MyWeatherApp):
def __init__(self, mainwindow):
self.address = StringVar() # use self.
ttk.Button(loc_entry, text="Get Forecast", command=run_it)
def run_it(self):
get_hourly_forecast(self.address.get())
或使用lambda
class MainWeatherHub(MyWeatherApp):
def __init__(self, mainwindow):
ttk.Button(loc_entry, text="Get Forecast", command=lambda:get_hourly_forecast(address.get()))
编辑: 我看到您在
get\u hourly\u forecast
中使用current\u weather
(StringVar
来自MainWeatherHub
)设置值当前天气。设置(设置[0])
您可以将当前天气作为参数发送到get\u hourly\u forecast
def get_hourly_forecast(cur_address, current_weather):
geocode_url = "...".format(cur_address, API_KEY)
current_weather.set(out[0])
及
但是从get\u hourly\u forecast
def get_hourly_forecast(cur_address):
geocode_url = "...".format(cur_address, API_KEY)
return out[0]
并将其放入运行它
def run_it(self):
result = get_hourly_forecast(self.address.get())
if result is not None:
self.current_weather.set(result)
这种方式get\u hourly\u forecast
不适用于StringVar
,您可以在其他不使用StringVar
的程序中使用它。此代码的结构非常不寻常。如果MainWeatherHub
是MainWeatherApp
的子类,则通常不会在MainWeatherApp
内部创建MainWeatherHub
的实例。这会使你所问问题的正确解决变得复杂。你愿意接受关于如何避免这种并发症的建议吗?布莱恩,非常感谢你的评估。我担心我的结构会引起并发症,变得不可持续。我对python比较陌生,甚至对构建GUI比较新,所以我喜欢对结构进行评论,我会采纳所有建议。分配给button方法,该方法使用参数address运行get\u hourly\u forecast
。get()
谢谢,Furas。非常简单的解决方案。现在我看到您也使用当前天气内部获取每小时天气预报-因此您还应该将其作为参数获取每小时天气预报(当前地址,当前天气):
或获取每小时天气预报()
应该使用返回[0]
和运行它()
应该得到它并放入当前天气
。我用当前天气
添加了示例,你找到了我的下一期,哈哈。谢谢你这么彻底。
def run_it(self):
result = get_hourly_forecast(self.address.get())
if result is not None:
self.current_weather.set(result)