Python+kivy+SQLite: How to set label initial value

2019-06-08 23:12发布

everyone,

I want to use kivy+Python to display items from a db file.

To this purpose I have asked a question before: Python+kivy+SQLite: How to use them together

The App in the link contains one screen. It works very well.

Today I have changed the App to two screens. The first screen has no special requirement but to lead the App to the second screen. In the second screen there is a label and a button. By clicking the button I want to have the label text changed. The label text refers to the car type from the db file that I have in the link above.

For this two screens design, I have two questions:

Question 1: How to update the label text when the button is clicked?

I tried with two methods:

Method A: self.ids.label.text = str(text)
It shows me the error message: AttributeError: 'super' object has no attribute '__getattr__' I have googled a lot but still cannot understand.

Method B: self.ids["label"].text = str(text) It shows me the error message: KeyError: 'label' I am confused because I have the label defined.

Question 2: How to set the label origin text to one of the car type, so that everytime the second screen is shown, there is already a car type shown.

Here is the code: (For the db file please refer to the link above.)

# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import ListProperty
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.graphics import Rectangle
from kivy.properties import NumericProperty, StringProperty, BooleanProperty, ListProperty
from kivy.base import runTouchApp
from kivy.clock import mainthread

import sqlite3
import random

class MyScreenManager(ScreenManager):

    def init(self, **kwargs):
        super().__init__(**kwargs)

        @mainthread  # execute within next frame
        def delayed():
            self.load_random_car()
        delayed()

    def load_random_car(self):
        conn = sqlite3.connect("C:\\test.db")
        cur = conn.cursor()

        cur.execute("SELECT * FROM Cars ORDER BY RANDOM() LIMIT 1;")

        currentAll = cur.fetchone()
        conn.close()
        currentAll = list(currentAll)   # Change it from tuple to list

        print currentAll

        current    = currentAll[1]
        print current
        self.ids.label.text = str(current)    # Method A
#        self.ids["label"].text = str(current) # Method B 

class FirstScreen(Screen):
    pass

class SecondScreen(Screen):
    pass

root_widget = Builder.load_string('''
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
MyScreenManager:
    transition: FadeTransition()
    FirstScreen:
    SecondScreen:

<FirstScreen>:
    name: 'first'
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: "First Screen"
            font_size: 30
        Button:
            text: 'Go to 2nd Screen'
            font_size: 30
            on_release:  app.root.current = 'second'

<SecondScreen>:
    name: 'second'
    BoxLayout:
        orientation: 'vertical'
        Label:
            id: label
            text: 'click to get a new car'   # I want its text changed when the button is clicked everytime. And its original text value should be one of the random car type from the db file.
            font_size: 30
        Button:
            text: 'Click to get a random car'
            font_size: 30
            on_release:  app.root.load_random_car()

''')

class ScreenManager(App):
    def build(self):
        return root_widget

if __name__ == '__main__':
    ScreenManager().run()

I have read a lot from internet, but I cannot understand them all. :-(

Please help me to correct the code. Thank you so much!

1条回答
聊天终结者
2楼-- · 2019-06-08 23:50
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.uix.widget import Widget

Builder.load_string("""
<ScreenX>
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: root.label_text
        Button:
            text: 'Click Me'
            on_release: root.on_clicked_button()
""")

class ScreenX(Widget):
    label_text = StringProperty("Default Value")
    def on_clicked_button(self):
        self.label_text = "New Text!"


class MyApp(App):
    def build(self):
        return ScreenX()

MyApp().run()

is typically how you would do this ...

查看更多
登录 后发表回答