I have a kivy program where I need the labels to populate with the data given from a function within my screen class. It works with the update button properly however I would also like for it to populate the labels on load. Here is the python file and the kv file:
py:
from kivy import * from kivy.app import App from kivy.clock import Clock from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen from kivy.properties import StringProperty import requests from bs4 import BeautifulSoup class CurrentHighScores(Screen): highscore = None highscore_two = None highscore_three = None highscore_four = None highscore_five = None label_start_one = StringProperty(' ') label_start_two = StringProperty(' ') label_start_three = StringProperty(' ') label_start_four = StringProperty(' ') label_start_five = StringProperty(' ') def speed_scraper(self): URL = 'http://algoodspeeders.org/alpr/speederid.php' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"} page = requests.get(URL, headers=headers) soup = BeautifulSoup(page.content, 'html.parser') indexes = [3, 5] speed_data = [] for tbody in soup.findAll('tbody'): for tr in tbody.findAll('tr'): speed_values = [td.text for td in tr.findAll('td')] speed_vals = [speed_values[x] for x in indexes] speed_data.append(speed_vals) speed_data.sort(reverse=True) # print(speed_data[0:5]) self.highscore = speed_data[0] self.highscore_two = speed_data[1] self.highscore_three = speed_data[2] self.highscore_four = speed_data[3] self.highscore_five = speed_data[4] self.ids.high_one.text = '1st: ' + str(self.highscore[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore[1]) self.ids.high_two.text = '2nd: ' + str(self.highscore_two[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_two[1]) self.ids.high_three.text = '3rd: ' + str(self.highscore_three[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_three[1]) self.ids.high_four.text = '4th: ' + str(self.highscore_four[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_four[1]) self.ids.high_five.text = '5th: ' + str(self.highscore_five[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_five[1]) print('High Scores List') print('----------------') print('1st: ' + str(self.highscore[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore[1])) print('2nd: ' + str(self.highscore_two[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore_two[1])) print('3rd: ' + str(self.highscore_three[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore_three[1])) print('4th: ' + str(self.highscore_four[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore_four[1])) print('5th: ' + str(self.highscore_five[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore_five[1])) class ScreenManage(ScreenManager): pass kv = Builder.load_file('algoodspeed.kv') class AlgoodSpeedApp(App): def build(self): return kv if __name__ == '__main__': AlgoodSpeedApp().run()
.kv:
ScreenManage: CurrentHighScores: <CurrentHighScores> name: 'CurrentHighScores' GridLayout: cols: 1 Label: name: 'current_high_scores' text: 'Current High Speeds For Cooper Rd:' font_size: 30 Label: id: high_one text: root.label_start_one Label: id: high_two text: root.label_start_two Label: id: high_three text: root.label_start_three Label: id: high_four text: root.label_start_four Label: id: high_five text: root.label_start_five Button: id: update text: 'Update Current High Speeds' on_release: root.speed_scraper()
I have tried using things like clock to delay the function call outside of the class but that doesn’t help at all. Thanks for the help!
Advertisement
Answer
Thanks to a comment on my question I did some more research and reworked the code slightly and this were my findings for anyone else who is having this issue. I use on_pre_enter to call my function and within the function simply update the “label” variables I have to change the text within the kv file. Here is how it looks. I left some of the old code in but commented it out so you can see kind of how it looked before:
.py:
from kivy import * from kivy.app import App from kivy.clock import Clock from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen from kivy.properties import StringProperty import requests from bs4 import BeautifulSoup class CurrentHighScores(Screen): def on_pre_enter(self, *args): self.speed_scraper() highscore = None highscore_two = None highscore_three = None highscore_four = None highscore_five = None label_start_one = StringProperty(' ') label_start_two = StringProperty(' ') label_start_three = StringProperty(' ') label_start_four = StringProperty(' ') label_start_five = StringProperty(' ') def speed_scraper(self): URL = 'http://algoodspeeders.org/alpr/speederid.php' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"} page = requests.get(URL, headers=headers) soup = BeautifulSoup(page.content, 'html.parser') indexes = [3, 5] speed_data = [] for tbody in soup.findAll('tbody'): for tr in tbody.findAll('tr'): speed_values = [td.text for td in tr.findAll('td')] speed_vals = [speed_values[x] for x in indexes] speed_data.append(speed_vals) speed_data.sort(reverse=True) # print(speed_data[0:5]) self.highscore = speed_data[0] self.highscore_two = speed_data[1] self.highscore_three = speed_data[2] self.highscore_four = speed_data[3] self.highscore_five = speed_data[4] self.label_start_one = ('1st: ' + str(self.highscore[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore[1])) self.label_start_two = ('2nd: ' + str(self.highscore_two[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_two[1])) self.label_start_three = ('3rd: ' + str(self.highscore_three[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_three[1])) self.label_start_four = ('4th: ' + str(self.highscore_four[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_four[1])) self.label_start_five = ('5th: ' + str(self.highscore_five[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_five[1])) '''self.ids.high_one.text = '1st: ' + str(self.highscore[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore[1]) self.ids.high_two.text = '2nd: ' + str(self.highscore_two[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_two[1]) self.ids.high_three.text = '3rd: ' + str(self.highscore_three[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_three[1]) self.ids.high_four.text = '4th: ' + str(self.highscore_four[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_four[1]) self.ids.high_five.text = '5th: ' + str(self.highscore_five[0]) + ' MPH | ' + 'License Plate No. ' + str( self.highscore_five[1]) print('High Scores List') print('----------------') print('1st: ' + str(self.highscore[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore[1])) print('2nd: ' + str(self.highscore_two[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore_two[1])) print('3rd: ' + str(self.highscore_three[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore_three[1])) print('4th: ' + str(self.highscore_four[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore_four[1])) print('5th: ' + str(self.highscore_five[0]) + ' MPH | ' + 'License Plate No. ' + str(self.highscore_five[1])) ''' class ScreenManage(ScreenManager): pass kv = Builder.load_file('algoodspeed.kv') class AlgoodSpeedApp(App): def build(self): return kv if __name__ == '__main__': AlgoodSpeedApp().run()
.kv
ScreenManage: CurrentHighScores: <CurrentHighScores> name: 'CurrentHighScores' on_enter: print('working') GridLayout: cols: 1 Label: name: 'current_high_scores' text: 'Current High Speeds For Cooper Rd:' font_size: 30 Label: id: high_one text: root.label_start_one Label: id: high_two text: root.label_start_two Label: id: high_three text: root.label_start_three Label: id: high_four text: root.label_start_four Label: id: high_five text: root.label_start_five Button: id: update text: 'Update Current High Speeds' on_release: root.speed_scraper()