2016-05-12 134 views
0

我試圖製作一個使用MySQL服務器數據的應用程序。到目前爲止,我一直很好,直到我偶然發現需要更新標籤。如何在按下按鈕後動態更新Kivy標籤

這是我到目前爲止有:

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() 

我在def qchange(self) mehod,因爲它傳遞到def db_data(self, query=q)一個新的查詢特別感興趣;因此請求被髮送到數據庫並返回一個字符串數組。但是,此數組不會被更進一步處理,並且GL小部件中的標籤不會更新。我想我需要添加在MainView中調用__init__的時鐘,但這只是一個猜測,因爲我也讀過關於使用屬性的內容(我不知道如何在此處使用它)

I'我編了我的代碼。現在,它看起來像這樣:

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() 

通過添加

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) 

我想根據給定的建議添加自定義網格佈局,不過,現在我得到一個錯誤說:

AttributeError: 'LabelsGrid' object has no attribute '_trigger_layout' 

關於如何處理這個問題的任何想法?

回答

0

創建自定義網格佈局,比如LabelsGrid,並在該類中實現一個方法show_labels。例如:

class LabelsGrid(GridLayout): 

    def show_labels(self, strings): 
     self.clear_widgets() 

     for text in strings: 
      label = Label(text=text) 
      self.add_widget(label) 

這樣,每次調用列表中標籤名稱的方法時,它都會自行更新。

+0

請問,你可以解釋一下,因爲我已經在__init__方法中有一個GridLayout小部件。根據你的建議,我應該添加這個類到MainView類,不是嗎?我應該如何處理已經是GridLayout的GL小部件? –

+0

@JohnAward用這個自定義網格佈局替換舊的網格佈局。 – jligeza