2015-05-23 3 views
2

Я очень новичок в программировании, поэтому, пожалуйста, извините меня, если мне не хватает правильной терминологии.ТипError: объект «Погода» не может быть вызван

Я пытаюсь получить изображение с веб-сайта и разместить его в графическом интерфейсе с помощью tkinter. Он работает, поскольку он размещает изображение в графическом интерфейсе; однако он по-прежнему производит ошибку в соответствии с заголовком этого сообщения.

Раздел кода, который вызывает ошибку следующим образом:

raw_data = BeautifulSoup(urllib.request.urlopen("http://www.weather.com.au/act/canberra").read()) 
    image = raw_data("img", ("class", "si"))[0] 
    image = image["src"] 
    if image == ("/images/icons/5.gif"): 
     URL = urllib.request.urlopen("http://www.weather.com.au/images/icons/5.gif").read() 
     b64_data = base64.encodestring(URL) 
     image = PhotoImage(data = b64_data) 
     label = Label(self, image = image).grid(row = 1, column = 2) 
     self(image) 

сужен дальше, кажется, линия 39 вызывает ошибку.

self(image) 

Полная программа выглядит следующим образом:

#!/usr/bin/env python 
from tkinter import * 
import sys 
import urllib.request 
from urllib.request import urlopen 
import base64 
from bs4 import BeautifulSoup 

class Weather(Frame): 

    def __init__(self, master): 
     Frame.__init__(self, master) 
     self.configure(bg = "#ededed") 
     self.grid() 
     self.heading = Label(self, bg = "#ededed", text = "  Temperature  ").grid(row = 0, column = 1, pady = 5) 
     self.heading = Label(self, bg = "#ededed", text = "  Picture  ").grid(row = 0, column = 2, pady = 5) 

     button = Button(self, bg = "#ededed", text = "Canberra", command = self.canberra_data).grid(row = 3, column = 0, sticky = EW) 

     self.obsVar1 = StringVar() 
     label = Label(self, textvariable = self.obsVar1, bg = "#e5e5e5", fg = "#751974").grid(row = 1, column = 1) 
     self.obsVar1.set("") 

    def canberra_data(self): 
     soup = BeautifulSoup(urllib.request.urlopen("http://www.bom.gov.au/act/observations/canberra.shtml").read()) 
     table = soup.find("table", {"id" : "tCANBERRA"}).tbody("tr", "rowleftcolumn") 
     for row in soup("th", {"id" : "obs-station-canberra"}): 
      for temp in soup("td", {"headers" : "obs-temp obs-station-canberra"}):                  
       self.obsVar1.set(temp.text) 

     raw_data = BeautifulSoup(urllib.request.urlopen("http://www.weather.com.au/act/canberra").read()) 
     image = raw_data("img", ("class", "si"))[0] 
     image = image["src"] 
     if image == ("/images/icons/5.gif"): 
      URL = urllib.request.urlopen("http://www.weather.com.au/images/icons/5.gif").read() 
      b64_data = base64.encodestring(URL) 
      image = PhotoImage(data = b64_data) 
      label = Label(self, image = image).grid(row = 1, column = 2) 
      self(image) 

master = Tk() 
master.title("Weather Program") 
app = Weather(master) 
master.mainloop() 

Я хотел бы добавить, что если сайт не обновила свой имидж, и это уже не «5.gif» (будучи значок погоды это весьма вероятно), то изображение не появится.

Любая помощь или направление были бы очень признательны. Я выглядел высоко и низко, но безрезультатно. Заранее спасибо.

+0

ли вы любезны отметить линию 39 пожалуйста ??? –

+0

Извините, это мой первый пост, поэтому я все еще изучаю веревки. Как вы отмечаете линию? – SGB

ответ

0

Вы не можете вызвать объект как функцию. Когда вы говорите self(image) в своем коде, вы пытаетесь вызвать объект. Если вы хотите это сделать, вам необходимо реализовать метод __call__. Однако я закодировал ваш пример и внес изменения в него. Пожалуйста, запустите его. Я надеюсь, что это помогает

#!/usr/bin/env python 
from tkinter import * 
import sys 
import urllib.request 
from urllib.request import urlopen 
import base64 
from bs4 import BeautifulSoup 

class Weather(Frame): 

    def __init__(self, master): 
     Frame.__init__(self, master) 
     self.configure(bg = "#ededed") 
     self.grid() 
     self.heading = Label(self, bg = "#ededed", text = "  Temperature  ").grid(row = 0, column = 1, pady = 5) 
     self.heading = Label(self, bg = "#ededed", text = "  Picture  ").grid(row = 0, column = 2, pady = 5) 

     button = Button(self, bg = "#ededed", text = "Canberra", command = self.canberra_data).grid(row = 3, column = 0, sticky = EW) 

     self.obsVar1 = StringVar() 
     label = Label(self, textvariable = self.obsVar1, bg = "#e5e5e5", fg = "#751974").grid(row = 1, column = 1) 
     self.obsVar1.set("") 

    def canberra_data(self): 
     soup = BeautifulSoup(urllib.request.urlopen("http://www.bom.gov.au/act/observations/canberra.shtml").read()) 
     table = soup.find("table", {"id" : "tCANBERRA"}).tbody("tr", "rowleftcolumn") 
     for row in soup("th", {"id" : "obs-station-canberra"}): 
      for temp in soup("td", {"headers" : "obs-temp obs-station-canberra"}): 
       self.obsVar1.set(temp.text) 

     raw_data = BeautifulSoup(urllib.request.urlopen("http://www.weather.com.au/act/canberra").read()) 
     image = raw_data("img", ("class", "si"))[0] 
     image = image["src"] 
     if image == ("/images/icons/5.gif"): 
      URL = urllib.request.urlopen("http://www.weather.com.au/images/icons/5.gif").read() 
      b64_data = base64.encodestring(URL) 
      image = PhotoImage(data = b64_data) 
      label = Label(self, image = image) 
      label.image = image 
      label.grid(row=1,column=2) 

master = Tk() 
master.title("Weather Program") 
app = Weather(master) 
master.mainloop() 

разн из ваших и моя версия выглядит следующим образом:

<    label = Label(self, image = image).grid(row = 1, column = 2) 
<    self(image) 
--- 
>    label = Label(self, image = image) 
>    label.image = image 
>    label.grid(row=1,column=2) 
+0

Спасибо, спасибо, спасибо! Какой потрясающий ресурс. Я все еще немного туман с концепцией объектов, но со временем узнаю. – SGB

+0

Я более чем счастлив, что сейчас он работает; однако в идеале я бы хотел, чтобы ярлык = Ярлык (self, image = image) .grid (row = 1, column = 2) находился в функции def __init__, как и для других меток.Возможно ли это с моей программой? Это улучшение, которое я хотел бы реализовать, поэтому мне не нужно повторять позиционирование метки в сетке. Мне нужно сохранить изображение в переменной, как у меня для температуры; однако я не разработал, как это сделать. Любые предложения снова будут высоко оценены. – SGB

0

Неверная строка, содержащая self (изображение). «Я» не является классом, это объект. Итак, если вы хотите создать объект типа Weather и передать что-то его конструктору, просто вызовите Weather (изображение).

+0

Я попытался это сделать, но, к сожалению, он все еще вызывает ошибку: AttributeError: объект 'PhotoImage' не имеет атрибута '_w' – SGB

+0

Он швыет новую ошибку, связанную с конструктором класса Frame. Возможно ли показать полную ошибку трассировки стека. Вы должны посмотреть на код конструктора кадров, чтобы узнать, что не так. –

+0

Полная ошибка довольно длинная (21 строка). Я не уверен, поможет ли это, но начинается с: Исключение в обратном вызове Tkinter. Кажется, он указывает на файл tkinter __init__.py. Последние несколько строк: Файл «/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/tkinter/__init__.py», строка 2070, в _setup , если master._w == '. ': AttributeError: объект' PhotoImage 'не имеет атрибута' _w ' – SGB