如何确保某些类和函数调用可以访问所有GUI输入变量?

时间:2019-04-23 14:37:53

标签: python-3.x oop tkinter

当我在输入栏中提供地址和/或位置并按“获取预测”按钮时,脚本在第22行失败。我认为由于str(address.get())找不到而引发了错误地址变量,可能是因为该变量在技术上在运行时不存在(由于该函数的结构,我无法记录错误)。

我的问题是;如何确保我的“ get_hourly_forecast”函数能够访问地址输入变量?

我尝试在各个位置(例如在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()

如果此脚本正常运行,则应返回输入栏中提供的位置的当前温度(以华氏度为单位)。

1 个答案:

答案 0 :(得分:0)

您应将其作为参数发送

def get_hourly_forecast(cur_address):
    geocode_url = "...".format(cur_address, API_KEY)

然后设置为按钮功能,该功能使用字符串运行get_hourly_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()))   

编辑:

我看到您使用current_weather中的StringVar(来自MainWeatherHub的{​​{1}})来设置值get_hourly_forecast

您可以将current_weather作为参数发送到current_weather.set(out[0])

get_hourly_forecast

def get_hourly_forecast(cur_address, current_weather):
    geocode_url = "...".format(cur_address, API_KEY)

    current_weather.set(out[0])

但是最好从class MainWeatherHub(MyWeatherApp): def __init__(self, mainwindow): self.address = StringVar() # use self. self.current_weather = StringVar() # use self. ttk.Button(loc_entry, text="Get Forecast", command=run_it) def run_it(self): get_hourly_forecast(self.address.get(), self.current_weather) 返回值

get_hourly_forecast

并将其放入def get_hourly_forecast(cur_address): geocode_url = "...".format(cur_address, API_KEY) return out[0]

run_it

这种方式 def run_it(self): result = get_hourly_forecast(self.address.get()) if result is not None: self.current_weather.set(result) 不能与get_hourly_forecast一起使用,您可以在不使用StringVar的其他程序中使用它。