Witam. Pisze program który pobiera dane z 2 stron na temat niektórych kursów walut i wyświetla je w programie okienkowym w etykietach. chciałem zrobić do tego przycisk do odświeżania, który po wciśnięciu ponownie pobiera dane i aktualizuje etykiety. Po wciśnięciu przycisku program zawiesza się, i odwiesza dopiero po wykonaniu wszystkich funkcji. Jak to naprawić? Dodatkowo nie zawsze się kursy aktualizują, czasem gdy wcisnę 2 razy pod rząd nic się nie dzieje.
from tkinter import *
import json
import urllib.request, urllib.parse
from bs4 import BeautifulSoup
import pandas
class Application(Frame):
def __init__(self):
super().__init__()
self.creatingRequest()
self.downloadCurrency()
self.createDataFrame()
self.initUI()
def initUI(self):
"""initialise UI"""
self.master.title("Exchange Rates")
self.master.geometry("560x500")
self.pack(fill = BOTH, expand = 1)
#creating Labels
valueLabel = Label(self, text = "AVERAGE RATE")
valueLabel.grid(row = 1, column = 0, sticky = E)
percentageLabel = Label(self, text = "PERCENTAGE CHANGE")
percentageLabel.grid(row = 2, column = 0, sticky = E)
timeLabel = Label(self, text = "TIME DOWNLOAD")
timeLabel.grid(row = 3, column = 0, sticky = E)
buyLabel = Label(self, text="BUY RATES")
buyLabel.grid(row=4, column=0, sticky=E)
sellLabel = Label(self, text="SELL RATES")
sellLabel.grid(row=5, column=0, sticky=E)
for i, item in enumerate(self.dataframe_averager["title"]):
rowLabel = Label(self, text = self.dataframe_averager["title"][i])
rowLabel.grid(row = 0, column = i+1, pady = 5, padx = 4)
for i, item in enumerate(self.dataframe_averager["value"]):
rowLabel = Label(self, text = self.dataframe_averager["value"][i])
rowLabel.grid(row = 1, column = i+1, pady = 5, padx = 4)
for i, item in enumerate(self.dataframe_averager["percentage"]):
rowLabel = Label(self, text = self.dataframe_averager["percentage"][i])
rowLabel.grid(row = 2, column = i+1, pady = 5, padx = 4)
for i, item in enumerate(self.dataframe_averager["time download"]):
rowLabel = Label(self, text = self.dataframe_averager["time download"][i])
rowLabel.grid(row = 3, column = i+1, pady = 5, padx = 4)
for i, item in enumerate(self.dataframe_averager["buy rates"]):
rowLabel = Label(self, text = self.dataframe_averager["buy rates"][i])
rowLabel.grid(row = 4, column = i+1, pady = 5, padx = 4)
for i, item in enumerate(self.dataframe_averager["sell rates"]):
rowLabel = Label(self, text = self.dataframe_averager["sell rates"][i])
rowLabel.grid(row = 5, column = i+1, pady = 5, padx = 4)
refreshButton = Button(self, text = "Refresh", width = 10, bg = "grey", command = self.onClick) #przycisk o którym mowa
refreshButton.grid(column = 7, row = 0, padx = 4, pady = 5)
def creatingRequest(self):
"""Creating requests and getting response"""
headers = {"user-agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"}
#Download "average" rates HTML
try:
request = urllib.request.Request("https://kursy-walut.mybank.pl", headers = headers)
response = urllib.request.urlopen(request)
self.average_rates_HTML = response.read().decode("utf-8")
except IOError as e:
self.connectionError1 = e
print(self.connectionError1)
#Download "buying and selling" rates HTML
try:
request = urllib.request.Request("https://kursy-walut-kupno-sprzedaz.mybank.pl/", headers = headers)
response = urllib.request.urlopen(request)
self.buy_and_sell_HTML = response.read().decode("utf-8")
except IOError as e:
self.connectionError2 = e
print(self.connectionError2)
#download json file with time
try:
request = urllib.request.Request("https://kursy-na-zywo.mybank.pl/automat/kursy.json", headers=headers)
response = urllib.request.urlopen(request)
self.time_download_JSON = json.loads((response.read().decode("utf-8")))
except IOError as e:
print(e)
def downloadCurrency(self):
"""Download exchange rates"""
#Download averager rates items
soup = BeautifulSoup(self.average_rates_HTML, "html.parser")
self.titles_averager = [tit.get_text() for tit in soup.select("div.cen div.box_mini b.b1")]
self.values_averager = [val.get_text() for val in soup.select("div.cen div.box_mini b.b2")]
self.percentage_change_averager = [(perc.get_text())[0:5] for perc in soup.select("div.cen div.box_mini b.b3")]
self.percentage_change_class_averager = [" ".join(perc["class"])
for perc in soup.select("div.cen div.box_mini b.b3")]
self.percentage_change_withclass_averager = [str(self.percentage_change_class_averager[i])
+ " " + str(self.percentage_change_averager[i])
for i in range(6)]
#download buy and sell rates items
soup = BeautifulSoup(self.buy_and_sell_HTML, "html.parser")
self.buy_rates = []
self.sell_rates = []
self.time_items = []
i = 0
while i < 12:
buy_rates_strip = [buy.get_text() for buy in soup.select("div.cen div.box_mini_ks b.b2")]
self.buy_rates.append(buy_rates_strip[i])
i +=2
i=1
while i<12:
sell_rates_strip = [sell.get_text() for sell in soup.select("div.cen div.box_mini_ks b.b2")]
self.sell_rates.append(sell_rates_strip[i])
i+=2
#download time items from json
for i, item in enumerate(self.time_download_JSON):
self.time_items.append(self.time_download_JSON[item]["czas"])
if i == 5:
break
def createDataFrame(self):
"""Creating a Data Frames"""
self.dataframe_averager = pandas.DataFrame({"title": self.titles_averager,
"value": self.values_averager,
"percentage change": self.percentage_change_withclass_averager,
"time download": self.time_items,
"percentage": self.percentage_change_averager,
"buy rates": self.buy_rates,
"sell rates": self.sell_rates})
print(self.dataframe_averager)
def onClick(self):
self.creatingRequest()
self.downloadCurrency()
self.createDataFrame()
self.initUI()
def main():
window = Tk()
app = Application()
window.mainloop()
if __name__ == "__main__":
main()
Po wciśnięciu przycisku powinien sie zmienić chociaż czas
Edit problem rozwiązany. Funkcja otwarta w nowym wątku przy pomocy modułu threading