Ich versuche eine App zu erstellen, die Daten vom MySQL-Server verwendet. Bisher ging es mir gut, bis ich über die Notwendigkeit stolperte, die Labels zu aktualisieren.So aktualisieren Sie dynamisch Kivy-Labels, nachdem Sie die Taste gedrückt haben
Dies ist, was ich bisher:
from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.clock import Clock
import MySQLdb
class MainView(ScrollView):
def qchange(self):
query = 'SELECT * FROM `citiestovisit` ORDER BY `idcitiestovisit`'
self.db_data(query)
q = 'SELECT * FROM `citiestovisit` ORDER BY `Name`'
def db_data(self, query=q):
#vector = ListProperty()
vector = []
con = MySQLdb.connect(host="localhost", user="root", passwd="", db="cities")
cur = con.cursor()
cur.execute('SET NAMES `utf8`')
cur.execute(query)
result = cur.fetchall()
for row in result:
string = str(row[0]) + " " + str(row[1]) + " " + str(row[2])
vector.append(string)
print vector
return vector
def __init__(self, **kwargs):
kwargs['cols'] = 2
super(MainView, self).__init__(**kwargs)
GL = GridLayout(cols = 3, spacing=10, size_hint_y=None)
GL.bind(minimum_height=GL.setter('height'))
for row in self.db_data():
splitRow = row.split(" ")
for data in splitRow:
GL.add_widget(Label(text=data,size_hint_y=None, font_size='20sp'))
self.add_widget(GL)
Builder.load_string("""
<MenuScreen>:
BoxLayout:
GridLayout:
cols: 1
Button:
text: 'Goto settings'
on_press:
root.manager.transition.direction = 'left'
root.manager.current = 'settings'
Button:
text: 'Quit'
Label:
font_name: 'C:\Anonymous\Anonymous.ttf'
text: "picture here"
<SettingsScreen>:
""")
# Declare both screens
class MenuScreen(Screen):
pass
class SettingsScreen(Screen):
pass
ss = SettingsScreen(name='settings')
layout = BoxLayout(orientation='vertical')
BL = BoxLayout()
layout.add_widget(BL)
#Instance of a MainView class
MV = MainView()
def callback(instance):
sm.transition.direction = 'right'
sm.current = 'menu'
def callback2(instance):
MV.qchange()
btn = Button(text="Back to Menu")
btn.bind(on_press=callback)
btn.size_hint = (1, 0.3)
BL.add_widget(btn)
btn2 = Button(text="Sort by ID")
btn2.size_hint = (1, 0.3)
btn2.bind(on_press=callback2)
BL.add_widget(btn2)
layout.add_widget(MainView())
sublayout = GridLayout(cols=3)
sublayout.add_widget(Label(text="hello"))
sublayout.add_widget(Label(text="World"))
sublayout.add_widget(Label(text="Python"))
layout.add_widget(sublayout)
ss.add_widget(layout)
# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(ss)
class MyApp(App):
def build(self):
return sm
if __name__ == '__main__':
MyApp().run()
Ich bin besonders interessiert in def qchange(self)
mehod wie es in def db_data(self, query=q)
geht eine neue Abfrage; Als Ergebnis wird eine Anfrage an die Datenbank gesendet und ein Array von Strings zurückgegeben. Dieses Array wird jedoch nicht weiter verarbeitet, und die Beschriftungen im GL-Widget werden nicht aktualisiert. Ich denke, ich muss die Uhr hinzufügen, die die __init__
in MainView nennen würde, aber es ist nur eine Vermutung, wie ich auch über die Verwendung von Eigenschaften gelesen habe (die ich nicht hier auch verwenden kann)
I ' Habe meinen Code editiert. Jetzt sieht es wie folgt aus:
class MainView(ScrollView):
def qchange(self):
query = 'SELECT * FROM `citiestovisit` ORDER BY `idcitiestovisit`'
#self.db_data(query)
#LG = self.LabelsGrid(self.GL)
q = 'SELECT * FROM `citiestovisit` ORDER BY `Name`'
def db_data(self, query=q):
vector = []
con = MySQLdb.connect(host="localhost", user="root", passwd="", db="cities")
cur = con.cursor()
cur.execute('SET NAMES `utf8`')
cur.execute(query)
result = cur.fetchall()
for row in result:
string = str(row[0]) + " " + str(row[1]) + " " + str(row[2])
vector.append(string)
print vector
return vector
class LabelsGrid(GridLayout):
def __init__(self, **kwargs):
self.cols = 3
self.spacing = 10
self.size_hint_y = None
def show_labels(self, strings):
self.clear_widgets()
for row in strings:
splitRow = row.split(" ")
for data in splitRow:
label = Label(text=data, size_hint_y=None, font_size='20sp')
self.add_widget(label)
GL = LabelsGrid()
def __init__(self, **kwargs):
kwargs['cols'] = 2
super(MainView, self).__init__(**kwargs)
self.GL=self.LabelsGrid()
# GL = GridLayout(cols = 3, spacing=10, size_hint_y=None)
self.GL.bind(minimum_height=self.GL.setter('height'))
self.GL.show_labels(self.db_data(self.q))
self.add_widget(self.GL)
#self.GL.clear_widgets()
Builder.load_string("""
<MenuScreen>:
BoxLayout:
GridLayout:
cols: 1
Button:
text: 'Goto settings'
on_press:
root.manager.transition.direction = 'left'
root.manager.current = 'settings'
Button:
text: 'Quit'
Label:
font_name: 'C:\Anonymous\Anonymous.ttf'
text: "picture here"
<SettingsScreen>:
""")
# Declare both screens
class MenuScreen(Screen):
pass
class SettingsScreen(Screen):
pass
ss = SettingsScreen(name='settings')
layout = BoxLayout(orientation='vertical')
BL = BoxLayout()
layout.add_widget(BL)
#Instance of a MainView class
MV = MainView()
def callback(instance):
sm.transition.direction = 'right'
sm.current = 'menu'
def callback2(instance):
MV.qchange()
btn = Button(text="Back to Menu")
btn.bind(on_press=callback)
btn.size_hint = (1, 0.3)
BL.add_widget(btn)
btn2 = Button(text="Sort by ID")
btn2.size_hint = (1, 0.3)
btn2.bind(on_press=callback2)
BL.add_widget(btn2)
layout.add_widget(MainView())
sublayout = GridLayout(cols=3)
sublayout.add_widget(Label(text="hello"))
sublayout.add_widget(Label(text="World"))
sublayout.add_widget(Label(text="Python"))
layout.add_widget(sublayout)
ss.add_widget(layout)
# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(ss)
class MyApp(App):
def build(self):
return sm
if __name__ == '__main__':
MyApp().run()
Durch die Zugabe von
class LabelsGrid(GridLayout):
def __init__(self, **kwargs):
self.cols = 3
self.spacing = 10
self.size_hint_y = None
def show_labels(self, strings):
self.clear_widgets()
for row in strings:
splitRow = row.split(" ")
for data in splitRow:
label = Label(text=data, size_hint_y=None, font_size='20sp')
self.add_widget(label)
Ich wollte Brauch hinzufügen Gridlayout nach einem bestimmten Ratschlag aber jetzt bekomme ich eine Fehlermeldung,:
AttributeError: 'LabelsGrid' object has no attribute '_trigger_layout'
Irgendwelche Ideen, wie man damit umgeht?
Könnten Sie, bitte, erklären, weil ich bereits ein GridLayout Widget in __init__ Methode habe. Gemäß Ihrem Vorschlag sollte ich diese Klasse zur MainView-Klasse hinzufügen, nicht wahr? Und was soll ich mit dem GL-Widget machen, das bereits ein GridLayout ist? –
@JohnAward Ersetzen Sie das alte Rasterlayout durch dieses benutzerdefinierte Rasterlayout. – jligeza