如何根据json文件内部内容在不同的屏幕上显示不同的问题和答案?

时间:2019-03-23 14:04:03

标签: python-3.x kivy

我正在尝试创建许多屏幕,每个屏幕都具有来自json文件的自己的问题和答案。 我是python的新手,似乎无法解决这个问题。 任何建议将不胜感激。

test.py

from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition, WipeTransition
from kivy.clock import Clock
from kivy.properties import (StringProperty, NumericProperty, ObjectProperty,
                         ListProperty, DictProperty, BooleanProperty)
from kivy.app import App
from kivy.uix.touchripple import TouchRippleBehavior
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.storage.jsonstore import JsonStore
from kivy.lang import global_idmap, Builder
import time
from kivy.storage.jsonstore import JsonStore


class SubjectsLayout(GridLayout):
    question_text = StringProperty()

    def __init__(self, **kwargs):
        super(SubjectsLayout, self).__init__(**kwargs)
        self.store = JsonStore('projectdata.json')
        self.retrieve_questions()
        self.retrieve_answers()

    def retrieve_questions(self):
        q = list(self.store.keys())

        self.question_text = q[0]

    def retrieve_answers(self):
        pass

class NavTray1(BoxLayout):
    pass


class RippleButton(TouchRippleBehavior, Button):

    def on_touch_down(self, touch):
        collide_point = self.collide_point(touch.x, touch.y)
        if collide_point:
            touch.grab(self)
            self.transparency = self.background_color[3]  
            self.background_color[3] = 0.5  
            self.ripple_show(touch)
            self.dispatch('on_press')
            return True
        return False

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            touch.ungrab(self)
            self.ripple_fade()
            def defer_release(dt):
                self.background_color[3] = self.transparency  
                self.dispatch('on_release')
            Clock.schedule_once(defer_release, self.ripple_duration_out)
            return True
        return False

class SurveyHeader(GridLayout):
    pass

class QuestionsScreen1(Screen):
    pass

class MyScreenManager(ScreenManager):    
    def new_page(self):
        if self.current is 'start':
            s = QuestionsScreen1(name='Question 1', id = 'Question1')
            self.add_widget(s)
            self.current = 'Question 1'
        elif self.current is 'Question 1':           
                s = QuestionsScreen1(name='Question 2', id = 'Question2')
                self.add_widget(s)
                self.current = 'Question 2'
        elif self.current is 'Question 2':             
                s = QuestionsScreen1(name='Question 3', id = 'Question3')
                self.add_widget(s)
                self.current = 'Question 3'



Login = Builder.load_string('''
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#: import SoundLoader kivy.core.audio.SoundLoader
#: import ScrollEffect kivy.effects.scroll.ScrollEffect
#: import SlideTransition kivy.uix.screenmanager.SlideTransition

MyScreenManager:
    transition: FadeTransition()
    QuestionsScreen1:

<NavTray1>:
    orientation: 'horizontal'
    padding: '5dp'
    spacing: '5dp'
    canvas.before:
        Color: 
            rgb: .1, .1, .1
        Rectangle:
            size: self.size
            pos: self.pos
    RippleButton:
        color: [0.4, 0.4, 0.4, 1]
        size_hint: (.33, None)
        height: '80dp'
        text: 'Back'

    BoxLayout:
        orientation: 'vertical'
        size_hint: (.33, 1.0)
        id: custom

    RippleButton:
        color: [6/255, 114/255, 0, 1]
        size_hint: (.33, None)
        height: '80dp'
        text: 'Forward'
        background_color: [28/138, 1, 35/138, 0.5]
        on_release : app.root.new_page()
        on_release : app.root.transition = SlideTransition(direction='left')




<QuestionsScreen1>:
    name: "start"
    BoxLayout:
        orientation: 'vertical'
        size: root.size
        pos: root.pos
        SurveyHeader:
            size_hint: (1.0, None)
            height: '90dp'
            id: header
        ScrollView:
            size_hint: (1.0, None)
            height: root.height - header.height - navtray.height
            SubjectsLayout:
            id: subjects
        NavTray1:
            size_hint: (1.0, None)
            id: navtray
            height: '90dp'

<SurveyHeader>:
    cols: 1
    canvas:
        Color:
            rgb: (.10, .1, .1)
        Rectangle:
            size: self.size
            pos: self.pos

<SubjectsLayout>:
    cols: 1
Label:
    size_hint_y : 0.25
    text: root.question_text
    font_size: "30dp"
GridLayout:
    cols: 2
    rows: 4
    size_hint_y : 0.75
    Label:
        text: 'a'
        font_size: "20dp" 
        size_hint_x : 0.8
    CheckBox:
        group: 'answer_group'
        size_hint_x : 0.2
    Label:
        text: 'b'
        font_size: "20dp"
        size_hint_x : 0.8
    CheckBox:
        group: 'answer_group'
        size_hint_x : 0.2
    Label:
        text: 'c'
        font_size: "20dp"
        size_hint_x : 0.8
    CheckBox:
        group: 'answer_group'
        size_hint_x : 0.2
    Label:
        text: 'd'
        font_size: "20dp"
        size_hint_x : 0.8
    CheckBox:
        group: 'answer_group'
        size_hint_x : 0.2


''')


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


if __name__ == "__main__":
    MyApp().run()

projectdata.json

{"Question 1": {"A": "1", "B": "2", "C": "3", "D": "4"}, "Question 2": {"A": "5", "B": "6", "C": "7", "D": "8"}}

我希望每个屏幕都应正确遵循json文件中的问题和答案。

1 个答案:

答案 0 :(得分:0)

问题2

  

我想知道是否有可能像第一屏一样   问题1,第二个屏幕出现问题2,依此类推   在Json文件中。我正在尝试提出更多的问题,所以   有更快的方法吗?

解决方案2

  • 使用屏幕名称,例如screenmanager.current

py-片段

    def retrieve_questions(self, dt=0):
        if self.store.count() > 0:
            self.question_text = App.get_running_app().root.current

            for key, val in self.store.get(self.question_text).items():
                if isinstance(self.ids[key], Label):
                    self.ids[key].text = str(val)
...
    def new_page(self):
        if self.current == 'Question 1':
            s = QuestionsScreen1(name='Question 2', id='Question2')
            self.add_widget(s)
            self.current = 'Question 2'
        elif self.current == 'Question 2':
            s = QuestionsScreen1(name='Question 3', id='Question3')
            self.add_widget(s)
            self.current = 'Question 3'

kv-片段

<QuestionsScreen1>:
    name: "Question 1"

输出2

Question 1 Question 2

问题1

  • 向每个ids添加Label,使其与Json文件中的相同。
  • 由于内部小部件的ids在内部小部件的__init__函数期间可能不可用,因此请使用Clock.schedule_once()来调用self.retrieve_questions
  • 检查非空Json商店

kv文件-片段

<SubjectsLayout>:
    cols: 1
    Label:
        size_hint_y : 0.25
        text: root.question_text
        font_size: "30dp"
    GridLayout:
        cols: 2
        rows: 4
        size_hint_y : 0.75
        Label:
            id: A
            text: 'a'
            font_size: "20dp"
            size_hint_x : 0.8
        CheckBox:
            group: 'answer_group'
            size_hint_x : 0.2
        Label:
            id: B
            text: 'b'
            font_size: "20dp"
            size_hint_x : 0.8
        CheckBox:
            group: 'answer_group'
            size_hint_x : 0.2
        Label:
            id: C
            text: 'c'
            font_size: "20dp"
            size_hint_x : 0.8
        CheckBox:
            group: 'answer_group'
            size_hint_x : 0.2
        Label:
            id: D
            text: 'd'
            font_size: "20dp"
            size_hint_x : 0.8
        CheckBox:
            group: 'answer_group'
            size_hint_x : 0.2

Py-代码段

class SubjectsLayout(GridLayout):
    question_text = StringProperty()

    def __init__(self, **kwargs):
        super(SubjectsLayout, self).__init__(**kwargs)
        self.store = JsonStore('projectdata.json')
        Clock.schedule_once(self.retrieve_questions, 1)

    def retrieve_questions(self, dt):
        if self.store.count() > 0:
            q = list(self.store.keys())

            self.question_text = q[0]
            for key, val in self.store.get(q[0]).items():
                if isinstance(self.ids[key], Label):
                    self.ids[key].text = str(val)

输出

Result