Как мне убедиться, что все входные переменные GUI могут быть доступны определенным классам и вызовам функций? - PullRequest
0 голосов
/ 23 апреля 2019

Когда я указываю адрес и / или местоположение в строке ввода и нажимаю кнопку «Получить прогноз», сценарий завершается с ошибкой в ​​строке 22. Я думаю, что возникает ошибка, потому что str (address.get ()) не может найти переменная адреса, вероятно, потому что она технически не существует во время выполнения (я не могу записать ошибку из-за структуры этой функции).

Мой вопрос; Как мне убедиться, что моя функция "get_hourly_forecast" может получить доступ к переменной ввода адреса?

Я пытался создать экземпляр переменной address в разных местах, например, в классе MainWeatherHub, а также в классе MyWeatherApp, а затем передать его в качестве аргумента в MainWeatherHub в строке 79, ни один из вариантов не сработал. Текущий код показывает первый вариант.

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 голосов
/ 24 апреля 2019

Вы должны отправить его как параметр

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) в get_hourly_forecast, чтобы установить значение current_weather.set(out[0]).

Вы можете отправить current_weather на 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, и вы можете использовать его в другой программе, которая не использует StringVar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...