Search code examples
pythonkivykivy-language

How to use the RST module in Kivy?


I'm creating a fitness/nutrition app in Kivy. The problem is that most of the screens involve text for the viewer to read and I don't want the text to be just plain old text like that of a .txt file. I tried looking for something and I found there is a RST rendering module that will make my text look good but after trying for a couple of days, I can't seem to get it working with my code. Also I want to put the text that I will be using with RST into a seperate file so I can keep my code clean, how would I be able to do that?

Python Code(main.py):

import kivy
kivy.require('1.9.0')

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ListProperty, StringProperty, OptionProperty, VariableListProperty
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.graphics import *
from kivy.base import runTouchApp
from kivy.uix.label import Label



class MainScreen(Screen):
    pass

class NutritionScreen(Screen):
    pass

class FitnessScreen(Screen):
    pass

class CalorcalcScreen(Screen):
    pass

class BigsixScreen(Screen):
    pass

class ProteinScreen(Screen):
    pass

class CarbScreen(Screen):
    pass

class FatScreen(Screen):
    pass

class VitaminScreen(Screen):
    pass

class MineralScreen(Screen):
    pass

class WaterScreen(Screen):
    pass

class SuppleScreen(Screen):
    pass

class DietScreen(Screen):
    pass

class ExerciseScreen(Screen):
    pass

class WorkoutplanScreen(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass


presentation = Builder.load_file("nutrifit.kv")

class NutrifitApp(App):

    def build(self):
        return presentation

nfApp = NutrifitApp()
nfApp.run()

Kivy Code(nutrifit.kv):

#: import FadeTransition kivy.uix.screenmanager.FadeTransition

ScreenManagement:

    transition: FadeTransition()
    MainScreen:
    NutritionScreen:
    FitnessScreen:
    CalorcalcScreen:
    BigsixScreen:
    SuppleScreen:
    DietScreen:
    ExerciseScreen:
    WorkoutplanScreen:
    ProteinScreen:
    CarbScreen:
    FatScreen:
    VitaminScreen:
    MineralScreen:
    WaterScreen:



<MainScreen>:
    name: 'main'
    GridLayout:
        cols: 1
        rows: 3
        spacing: 1
        padding: 1

        Button:
            text: "Nutrition"
            font_size: 25
            on_release: app.root.current = "nutrition"

        Button:
            text: "Fitness"
            font_size: 25
            on_release: app.root.current = "fitness"

################################################################################           

<NutritionScreen>:
    name: 'nutrition'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Home'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "main"

        Label:
            text: 'Nutrition'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"center": 1, "top": 1}


    BoxLayout:
        orientation: 'vertical'
        size_hint: 1, .9

        Button:
            text: "Caloric Calculator"
            font_size: 25
            on_release: app.root.current = "calorcalc"

        Button:
            text: "The Big Six"
            font_size: 25
            on_release: app.root.current = "bigsix"

        Button:
            text: "Supplementation"
            font_size: 25
            on_release: app.root.current = "supple"

        Button:
            text: "Diets"
            font_size: 25
            on_release: app.root.current = "diet"


<CalorcalcScreen>:
    name: 'calorcalc'
<BackBar@ButtonBehavior+BoxLayout>:
    orientation: 'horizontal'
    bgcolor: [1, 0, 0, 1]
    on_press: self.bgcolor = [1, 0, 0, .5]
    on_release: self.bgcolor = [1, 0, 0, 1]
    canvas:
        Color:
            rgba: root.bgcolor
        Rectangle:
            pos: self.pos
            size: self.size
    Label:
        text: '<--'
        size_hint_x: None
        width: root.height
    Label:
        text: 'Current name'
        text_size: self.size
        halign: 'left'
        valign: 'middle'

        RstDocument:
            text: root.text


<BigsixScreen>:
    name: 'bigsix'
    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "nutrition"



    GridLayout:
        cols: 2
        rows: 3
        size_hint: 1, .9
        Button:
            text: 'Protein'
            on_release: app.root.current = 'protein'
        Button:
            text: 'Carbohydrates'
            on_release: app.root.current = 'carb'
        Button:
            text: 'Fats'
            on_release: app.root.current = 'fat'
        Button:
            text: 'Vitamins'
            on_release: app.root.current = 'vitamin'
        Button:
            text: 'Minerals'
            on_release: app.root.current = 'mineral'
        Button:
            text: 'Water'
            on_release: app.root.current = 'water'


<ProteinScreen>:
    name: 'protein'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "bigsix"

        Label:
            text: 'Protein'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}

    FloatLayout:
        Label:
            text: 'this is protein'
            pos_hint: {"center_x": .5, "center_y": .5}

<CarbScreen>:
    name: 'carb'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "bigsix"

        Label:
            text: 'Carbohydrates'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}

    FloatLayout:
        Label:
            text: 'this is carbs'
            pos_hint: {"center_x": .5, "center_y": .5}

<FatScreen>:
    name: 'fat'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "bigsix"

        Label:
            text: 'Fats'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}

    FloatLayout:
        Label:
            text: 'this is fats'
            pos_hint: {"center_x": .5, "center_y": .5}

<MineralScreen>:
    name: 'mineral'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "bigsix"

        Label:
            text: 'Minerals'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}

    FloatLayout:
        Label:
            text: 'this is minerals'
            pos_hint: {"center_x": .5, "center_y": .5}

<VitaminScreen>:
    name: 'vitamin'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "bigsix"

        Label:
            text: 'Vitamins'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}

    FloatLayout:
        Label:
            text: 'this is vitamins'
            pos_hint: {"center_x": .5, "center_y": .5}

<WaterScreen>:
    name: 'water'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "bigsix"

        Label:
            text: 'Water'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}

    FloatLayout:
        Label:
            text: 'this is water'
            pos_hint: {"center_x": .5, "center_y": .5}





<SuppleScreen>:
    name: 'supple'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "nutrition"

        Label:
            text: 'Supplementation'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}


    BoxLayout:
        orientation: 'vertical'
        size_hint: 1, .9

<DietScreen>:
    name: 'diet'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "nutrition"

        Label:
            text: 'Diets'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}


    BoxLayout:
        orientation: 'vertical'
        size_hint: 1, .9




################################################################################


<FitnessScreen>:
    name: 'fitness'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Home'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "main"

        Label:
            text: 'Fitness'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}


    BoxLayout:
        orientation: 'vertical'
        size_hint: 1, .9

        Button:
            text: "Exercises"
            font_size: 25
            on_release: app.root.current = "exercise"

        Button:
            text: "The Big Six"
            font_size: 25
            on_release: app.root.current = "workoutplan"



<WorkoutplanScreen>:
    name: 'workoutplan'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "fitness"

        Label:
            text: 'Workout Plans'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}


    BoxLayout:
        orientation: 'vertical'
        size_hint: 1, .9




<ExerciseScreen>:
    name: 'exercise'

    BoxLayout:
        orientation: 'horizontal'
        spacing: 1
        padding: 1
        Button:
            text: 'Back'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
            on_release: app.root.current = "fitness"

        Label:
            text: 'Exercises'
            size_hint_y: .1
            size_hint_x: 1
            pos_hint: {"right": 1, "top": 1}


    BoxLayout:
        orientation: 'vertical'
        size_hint: 1, .9

This is if I set it to vertical:

first example

This is if I enter the parameters:

size_hint: .5, .1
pos_hint: {"x": 0, "top": 1}

second example


Solution

  • How to use RST Document in Kivy?

    Rreference: reStructuredText renderer

    Reading text from an input File:

    1. Create an input File - inFile.txt

    Create a file called "inFile.txt" with the following text:

    .. _top:
    
    Hello world
    ===========
    
    This is an **emphased text**, some ``interpreted text``.
    And this is a reference to top_::
    
        $ print("Hello world")
    

    2. Edit class CalorcalcScreen

    Replaced "pass" with the following code in your class CalorcalcScreen(Screen):

    class CalorcalcScreen(Screen):
        text = ""
        with open("inFile.txt") as fobj:
            for line in fobj:
                text += line
    

    3. Edit kv Rule file - nutrifit.kv

    At <CalcorcalcScreen>, replace "Label" with "RstDocument" and remove "document = RstDocument..."

    <CalorcalcScreen>:
        name: 'calorcalc'
        BoxLayout:
            orientation: 'horizontal'
            spacing: 1
            padding: 1
            Button:
                text: 'Back'
                size_hint: .25, .1
                pos_hint: {"x": 0, "top": 1}
                on_release: app.root.current = "nutrition"
    
            Label:
                text: ''
                size_hint_y: .1
                size_hint_x: 1
                pos_hint: {"right": 1, "top": 1}
    
    
        BoxLayout:
            orientation: 'vertical'
            size_hint: 1, .9
    
            RstDocument:
                text: root.text
    
    
    <BigsixScreen>:
    

    New Navigation Bar

    Edit kv Rule file

    Please update your kv rule file as follow:

    <BackBar@ButtonBehavior+BoxLayout>:
        orientation: 'horizontal'
        bgcolor: [1, 0, 0, 1]
        on_press: self.bgcolor = [1, 0, 0, .5]
        on_release: self.bgcolor = [1, 0, 0, 1]
        canvas:
            Color:
                rgba: root.bgcolor
            Rectangle:
                pos: self.pos
                size: self.size
        Label:
            text: '<--'
            size_hint: .25, .1
            pos_hint: {"x": 0, "top": 1}
        Label:
            text: 'Current name'
            text_size: self.size
            halign: 'left'
            valign: 'middle'
            size_hint: 1, .1
            pos_hint: {"right": 1, "top": 1}
    
    <CalorcalcScreen>:
        name: 'calorcalc'
        BackBar:
        BoxLayout:
            orientation: 'vertical'
            size_hint: 1, .9
    
            RstDocument:
                text: root.text
    
    <BigsixScreen>:
    

    Output

    App Started - Clicked Nutrition Nutrition Screen - Clicked Caloric Calculator Back Navigation Bar - RstDcoument Displayed New Navigation Back Bar - RstDocument Displayed