如何在按下按钮后动态更新Kivy标签

时间:2016-05-12 08:28:03

标签: mysql python-2.7 kivy updating

我试图制作一个使用MySQL服务器数据的应用程序。到目前为止,我做得很好,直到我偶然发现需要更新标签。

这是我到目前为止所做的:

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__的时钟,但这只是猜测,因为我还读过有关使用属性的内容(我不知道如何使用在这里使用)

我已编辑了我的代码。现在它看起来像这样:

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)

我想根据给定的建议添加自定义GridLayout,但是,现在我收到错误说:

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

有关如何处理此问题的任何想法?

1 个答案:

答案 0 :(得分: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)

这样,每次使用列表中的标签名称调用方法时,它都会自行更新。