当我的代码失去互联网时,如何防止 Tkinter 崩溃

How do I prevent Tkinter from crashing when my code loses internet

几个月前我在tkinter写了一个魔镜代码。当我成功时,它能够毫无问题地继续。由于驱动器问题,我不确定这是我的最终产品(为此我还删除了日历),但无论如何现在当我切断互联网时它通常不会响应。怎样才能顺利运行?我意识到这是一个相当大的部分,感谢我能得到的任何帮助。

""" MagicMirror
    Includes clock, and weather
"""

from __future__ import print_function
from apiclient.discovery import build
import calendar
from datetime import datetime, time, timedelta
from httplib2 import Http
import json
from oauth2client import file, client, tools
import PIL.Image, PIL.ImageTk
from PIL import ImageTk, Image
from platform import system
import requests
from tkinter import *


class GlobalVars:
    def __init__(self, is_Celcius, postalCode):
        self.celcius = is_Celcius
        self.zipCode = postalCode


#----------time----------
#delete seconds later


class Clock(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent, bg = "black")

        self.time = ""
        self.day = ""
        self.time_Label = Label(self, text = self.time, font =('Helvetica', 70, "bold"), fg = "white", bg = "black")
        self.time_Label.pack(anchor = E)
        self.day_Label = Label(self, text = self.day, font = ("Helvetica", 20, "italic"), fg = "white", bg = "black")
        self.day_Label.pack(side = RIGHT, anchor = E)
        self.tick()

    def tick(self):
        self.time_Label.config(text = str(datetime.now())[11:19])
        date = str(datetime.now())
        currentDay = calendar.day_name[datetime.strptime(str(datetime.now())[:10], "%Y-%m-%d").weekday()]\
        + ", " + calendar.month_name[int(date[5:7])] + " " + date[8:10]
        if self.day != currentDay:
            self.day = currentDay
            self.day_Label.config(text = self.day)
        print("Clock check")
        self.time_Label.after(1000, self.tick)


#--------weather---------


# allow for easy installment of multiple cities (through list of zipCodes?)
class Weather(Frame):
    def __init__(self, parent, celc, zipCode):
        Frame.__init__(self, parent, bg = "black")
        self.locations = list()

        if system() == "Darwin":  # MAC
            self.path = "./icons/"
        elif system() == "Linux":
            self.path = "/home/pi/Documents/MagicMirror_testing/icons/"
        else:  # PC
            self.path = "D:\MPZinke\Drive\Workspace\MagicMirror\icons\"
        self.pathDict = {"broken clouds" : "cloudy.jpg", "error" : "error.jpg", "few clouds" : "partCloudy.jpg", "foggy" : "foggy.jpg", 
                         "icey" : "icey.jpg", "light rain" : "rain.jpg", "mist" : "foggy.jpg", "overcast clouds" : "cloudy.jpg", 
                         "scattered clouds" : "partCloudy.jpg", "rain" : "rain.jpg", "scattered clouds" : "partCloudy.jpg", 
                         "snow" : "snow.jpg", "clear sky" : "sunny.jpg", "tStorms" : "tStorms.jpg", "wind" : "windy.jpg"}

        for loc in zipCode:
            self.locations.append(Location(self, celc, loc))
        self.weatherLoop()


    def weatherLoop(self):
        self.weatherIcons = list()
        for i in range(len(self.locations)):
            self.locations[i].update()

            try: path = self.path + self.pathDict[self.locations[i].weather[0]]
            except:  # handles unkown dictionary entries
                path = self.path + self.pathDict["error"]
                print(self.locations[i].weather[0])

            self.weatherIcons.append(PIL.ImageTk.PhotoImage(PIL.Image.open(path)))
            self.locations[i].labels[0].config(image = self.weatherIcons[i])

            self.locations[i].labels[4].pack(side = TOP, anchor = NW)
            self.locations[i].currentFrame.pack(side = TOP, anchor = NW)
            orientation = [LEFT, RIGHT, TOP, TOP]
            for j in range(len(self.locations[i].labels)-1):
                self.locations[i].labels[j].pack(side = orientation[j], anchor = NW)    

        print("Weather check")
        self.after(5000, self.weatherLoop)




class Location(Frame):
    def __init__(self, parent, celc, zipCode):
        Frame.__init__(self, parent, bg = "black")
        self.zipCode = str(zipCode)
        self.celc = celc

        self.labels = []
        self.currentFrame = Frame(parent, background = "black")

        parents = (self.currentFrame, self.currentFrame, parent, parent, parent)
        for i in parents:
            self.labels.append(Label(i, bg = "black", anchor = NW))

    def update(self):
        self.weather = organizeWeather(self.celc, self.zipCode)
        tempChar = "° F"
        if self.celc: tempChar = "° C"

        self.labels[1].config(text = self.weather[1] + tempChar, font = ("Helvetica", 45, "bold"), fg = "white")
        self.labels[2].config(text = "High: " + self.weather[2] + tempChar, font = ("Helvetica", 20, "bold"), fg = "white")
        self.labels[3].config(text = "Low: " + self.weather[3] + tempChar, font = ("Helvetica", 20, "bold"), fg = "white")
        self.labels[4].config(text = self.weather[4], font = ("Helvetica", 30, "underline"), fg = "white")  


#--------function--------


def getWeather(zipCode):
    address = "http://api.openweathermap.org/data/2.5/weather?zip=" + zipCode + "&appid=556f1331999ad8f3fedec7ba906ebb54"
    try: 
        weatherData = requests.get(address, timeout=6.0).json()
    except requests.ConnectionError: 
        weatherData = None
        print("Could not get weather", datetime.today())
    return weatherData


def organizeWeather(celc, zipCode):
    temp = []
    data = getWeather(zipCode)
    print(zipCode)
    if data:
        temp.append(data["weather"][0]["description"])  # (ie clear, cloudy, etc)
        temp.append(toCelcius(celc, data["main"]["temp"]))  # current temp
        temp.append(toCelcius(celc, data["main"]["temp_max"]))  # high
        temp.append(toCelcius(celc, data["main"]["temp_min"]))  # low
        temp.append(data["name"])
        return temp
    return ["error", "", "", "", ""]


def toCelcius(celcius, temp):
    temp = temp - 273.15
    if not celcius:
        temp = temp * 1.8 + 32
    return str(int(temp))



class TextWidget(Frame):
    def __init__(self, parent, words):
        Frame.__init__(self, parent, bg = "black")

        self.title1 = Label(self, text = words, font = ("Helvetica", 20, "bold"), fg = "white", bg = "black")
        self.title1.pack(side = LEFT, anchor = E)


class Startscreen:
    def __init__(self):
        # setup window
        self.tk = Tk()
        self.tk.title("MagicMirror")
        self.tk.configure(background = 'black')
        self.tk.geometry('1024x786')
        self.tk.resizable(500, 500)  # *

        self.constants = GlobalVars(True, ["77077"])

        # assign frames
        self.leftTop = Frame(self.tk, background = "black", width=500, height=500)
        self.rightTop = Frame(self.tk, background = "black", width=350, height=100)
        self.rightBottom = Frame(self.tk, background = "black", width=150, height=650)
        self.leftTop.pack(side = LEFT, fill = Y, expand = NO)
        self.rightTop.pack(side = TOP, expand = NO, anchor = NE)
        self.rightBottom.pack(side = RIGHT, fill = Y, expand = NO)

        # clock
        self.clock = Clock(self.rightTop)
        self.clock.pack(side = RIGHT, anchor = N, padx = 10, pady = 10, expand = NO)

        # weather
        self.weather = Weather(self.leftTop, self.constants.celcius, self.constants.zipCode)
        self.weather.pack(side = LEFT, anchor = NW)


if __name__ == "__main__":
    window = Startscreen()
    window.tk.mainloop()

您可以使用以下方法继续检查互联网,然后,如果您有互联网,则可以执行代码。如果没有,可以让用户知道没有连接。

import socket
REMOTE_SERVER = "www.google.com"
def is_connected(hostname):
  try:
    host = socket.gethostbyname(hostname)
    s = socket.create_connection((host, 80), 2)
    return True
  except:
     pass
  return False
is_connected(REMOTE_SERVER)