AttributeError:'_tkinter.tkapp'对象在tkinter中没有属性'text'

时间:2019-09-14 09:18:01

标签: python python-3.x tkinter error-handling

我设置了一个天气应用程序,但是当我单击按钮获取天气时出现此错误?在此应用程序中,我创建了thread来进行后台处理。 在这里,我试图获取self.text的值并在另一个函数中进行访问。

错误:

  

thread_weather_icon =线程(target = self.weather_icon,   args = {self.text,))文件   “ C:\ Users \ ABC \ AppData \ Local \ Programs \ Python \ Python37-32 \ lib \ tkinter__init __。py”,   第2101行,位于 getattr       返回getattr(self.tk,attr)AttributeError:'_tkinter.tkapp'对象没有属性'text'

我不知道为什么会收到此错误?

我尝试更改此设置,但仍然遇到错误:

class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk().__init__(self, *args, **kwargs)

        super().__init__()

        self.title('AccWeather')
        self.geometry('600x500')

我的代码:

import requests
from tkinter import *
from bs4 import BeautifulSoup
from threading import  Thread
from io import BytesIO
from PIL import ImageTk, Image

class gui(Tk):
    def __init__(self):
        Tk.__init__(self)

        # title of app
        self.title('AccWeather')
        self.geometry('600x500')

        # API
        self.api = 'cKh5lrrqb7L26PC9OFyuj1S1y14oPMCh'

        # main canvas with image
        url = 'https://images.unsplash.com/photo-1451154488477-d20dee2a4e46?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=753&q=80'
        img = requests.get(url).content
        self.img = ImageTk.PhotoImage(Image.open(BytesIO(img)))
        self.main = Label(self, image=self.img)
        self.main.place(relx=.0, rely=.0, relwidth=1, relheight=1)




        # button and input
        self.city = Entry(self.main, bd=0, font=3, fg='black')
        self.city.place(relx=0.1, rely=0.1, relheight=0.1, relwidth=0.6)
        Button(self.main, text='Get Weather', bg='DodgerBlue',font=5, bd=1, command=self.get_weather_call).place(relx=0.7, rely=.1, relheight=0.1,relwidth=0.2)

        # API box
        Label(self.main, bg='white', text='API key: ').place(relx=0.1, rely=0)
        self.api_box = Entry(self.main, bd=1, font=2)
        self.api_box.place(relx=0.2, rely=0, relwidth=.7)
        self.api_box.insert(0, self.api)


        # output label
        Label(self.main, text='OUTPUT:', fg='black',bg='white', font=5).place(relx=.1, rely=.3)
        # output box
        self.put_out = Label(self.main, font=20, anchor='nw', bg='white', justify='left', bd=5)  # border = bd
        self.put_out.place(relx=.1, rely=.4, relwidth=.8, relheight=.5)


        # weather icon
        self.icon = Label(self.main, height=200, width=200, bg='white')
        self.icon.place(relx=.7, rely=.4, relwidth=.2, relheight=.2)
        self.photo = None



    def get_weather_call(self):
       city = self.city.get()

        thread1 = Thread(target=self.get_weather, args=(city,))
        thread1.start()

        text = self.text

        thread_weather_icon = Thread(target=self.weather_icon, args=(text,))
        thread_weather_icon.start()


    def get_weather(self, city):
        # autocomplete location
        try:
            auto_url = f"http://dataservice.accuweather.com/locations/v1/cities/autocomplete?apikey={self.api}&q=" + city
            data = requests.get(auto_url).json()
            check = ''
            for i in data:
                for a in i:
                    if a=='ServiceUnavailable':
                        check = True
            if  check:
                self.put_out['text'] = 'Error: '+data['Message']
            else:
                try:
                    key = data[0]['Key']
                    city_name = ', '.join([data[0]['LocalizedName'], data[0]['Country']['LocalizedName']])
                    api = requests.get(f"http://dataservice.accuweather.com/currentconditions/v1/{key}?apikey={self.api}").json()

                    temp = api[0]['Temperature']['Metric']['Value']
 This is self----> self.text = api[0]['WeatherText']
                    weather = f'City: {city_name}\nTemperature (c): {int(temp)}\nCondition: {self.text}'
                    self.put_out['text'] = weather

                except Exception as e:
                    self.put_out['text'] = e
        except Exception as e:
            print(e)

    def weather_icon(self, txt):
        split = txt.split(' ')
        get_text = '+'.join(split)
        print(get_text)
        url = 'https://www.iconfinder.com/search/?q='+get_text
        req = requests.get(url).content
        soup = BeautifulSoup(req, 'html.parser')
        img_url = soup.find('img', {'class': 'd-block'})['src']
        image_content = requests.get(img_url).content
        self.photo = ImageTk.PhotoImage(Image.open(BytesIO(image_content)))
        self.icon['image'] = self.photo



if __name__ == '__main__':
    start = gui()
    start.mainloop()

请,我能理解吗。

1 个答案:

答案 0 :(得分:1)

self.weather_icon需要在self.text中创建的self.get_weather,因此self.get_weather必须在self.weather_icon之前运行,而self.weather_icon必须等到{{ 1}}结束其工作-确保self.get_weather已经存在。

最好将两个函数的代码放到一个函数中,然后在一个线程中运行。

self.text