Search code examples
pythonpython-3.xkivytoolbarkivy-language

Kivy MDToolBar right_action_items: Can't change Screens


For the life of me I can't seem to figure out how to use the MDToolBar right_action_items: in kv to change screens. I know that with a button on_release: I can add a simple app.root.current = 'analyzer' (I defined my screen as 'analyzer' and 'main').

Yet you can't add this code to a right_action_items: Lambda x: app.root.current = 'analyzer' in kv. So I tried adding a function in python that would do this for me inside my Manager(ScreenManager) -->

def change_screen(self, inst):
    Manager.current = f'{inst.ids.main.text}'

But it doesn't work... I'm lost, confused, afraid... help. me. please...

main.py

from kivymd.app import MDApp
from kivymd.theming import ThemeManager
from kivymd.uix.dialog import MDDialog
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.uix.list import TwoLineListItem
from kivymd.uix.button import MDIconButton
from kivymd import *

from PyDictionary import PyDictionary
import sys
import json
import requests


class Manager(ScreenManager):
    def change_screen(self, inst):
        Manager.current = f'{inst.ids.main.text}'

class Main(Screen):
    """main application goes here"""
    def close_dialog(self, obj):
        self.dialog.dismiss()

    def show_data(self):
        message = """
        Think of Probably Knot (PK) as a study
        guide of sorts. Helping the user guide
        himself.

        This little program was designed to help
        re-think ones sentences and therefore 
        find new solutions. By changing ones
        perception, things can become more clear
        where once they were misunderstood.

        PK re-shuffle a word from an input
        sentence to help rephrase ones 
        orignal sentence. To better
        understand problems and ideas by
        changing the angle of perception
        with more elegant solutions.
        """
        close = MDIconButton(icon="close-circle", on_release=self.close_dialog)
        #more = MDIconButton(icon="more")
        self.dialog = MDDialog(title="Probably Knot Helper", text=message,
                         size_hint=(0.8, 1), buttons=[close])
        self.dialog.open()


class Analyzer(Screen):
    def analyze(self, main): # main is pointing to ---> Main().show_data()
        """Analyse data with PyDictionary"""

        sent = main.ids.sentence.text.lower()
        wrd = main.ids.word.text.lower()
        print(sent, wrd)

        # Definition Section #
        dictionary = PyDictionary()
        define_wrd = dictionary.meaning(wrd)

        if wrd != '' and sent != '':
            API_KEY = 'a701e74e453ee6695e450310340401f5'
            URL = f'http://words.bighugelabs.com/api/2/{API_KEY}/{wrd}/json'

            if wrd not in sent:
                print("i made it")
                error = MDDialog(title="Error", text=f"Word: '{wrd}' is not in\n\n'{sent}'")
                error.open()
            else:
                r = requests.get(URL) # get's url json file
                j = json.loads(r.text) # loads json into 'j' as a dict

                if type(j) == dict: # check is 'j' variable is coming in as a Dict holds the new sentences new = f"{result}\n"
                    final_set = set()
                    try:
                        for w in j['adjective']['syn']:
                            final_set.add(w)
                    except KeyError:
                        print(f'Adjective for "{wrd}" is not found.')
                    try:
                        for w in j['noun']['syn']:
                            final_set.add(w)
                    except KeyError:
                        print(f'Noun for "{wrd}" is not found.') 
                    try:
                        for w in j['verb']['syn']:
                            final_set.add(w)
                    except KeyError:
                        print(f'Verb for "{wrd}" is not found.')
                    item = TwoLineListItem(text=f"Original: {sent}", secondary_text=f"{wrd}")
                    self.ids.container.add_widget(item)
                    for word in final_set:
                        item = TwoLineListItem(text=f"{sent.replace(wrd, word)}", secondary_text=f"{word}")
                        self.ids.container.add_widget(item)
                    # try:
                    #     for num, w in enumerate(j['adjective']['syn'], 1):
                    #         item = OneLineListItem(text=f"{num}: {sent.replace(wrd, w)}\n")
                    #         self.ids.container.add_widget(item)
                    # except KeyError:
                    #     print(f'Adjective for "{wrd}" is not found.')
                    # try:
                    #     for num, w in enumerate(j['noun']['syn'], 1):
                    #         item = OneLineListItem(text=f"{num}: {sent.replace(wrd, w)}\n")
                    #         self.ids.container.add_widget(item)
                    # except KeyError:
                    #     print(f'Noun for "{wrd}" is not found.') 
                    # try:
                    #     for num, w in enumerate(j['verb']['syn'], 1):
                    #         item = OneLineListItem(text=f"{num}: {sent.replace(wrd, w)}\n")
                    #         self.ids.container.add_widget(item)
                    # except KeyError:
                    #     print(f'Verb for "{wrd}" is not found.')


class ProbablyKnotApp(MDApp):
    def build(self):
        self.theme_cls = ThemeManager()
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Amber"
        self.theme_cls.primary_hue = "A700"

        return Manager()

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

kv

<Manager>:
    Main:
        id: main
        name: 'main'
    Analyzer:
        id: analyze
        name: 'analyzer'


<Main>:
    BoxLayout:
        orientation: 'vertical'
        MDToolbar:
            id: toolbar
            title: "Probably Knot v3"
            md_bg_color: app.theme_cls.primary_color
            right_action_items: [["help-circle-outline", lambda x: app.root.get_screen('main').show_data()]]
        MDFloatLayout:
            MDTextField:
                id: sentence
                icon_right: "book-open-outline"
                icon_right_color: app.theme_cls.primary_color

                hint_text: "Enter Sentence"
                helper_text: "Write a problem statement to analyze"
                helper_text_mode: "on_focus"
                multiline: False
                pos_hint: {'center_x': 0.5, 'center_y': 0.7}
                size_hint_x: None
                width: root.width - dp(20)
            MDTextField:
                id: word
                icon_right: "lead-pencil"
                icon_right_color: app.theme_cls.primary_color

                hint_text: "Enter Word"
                helper_text: "Write ONE word from the above sentence"
                helper_text_mode: "on_focus"
                multiline: False
                pos_hint: {'center_x': 0.5, 'center_y': 0.6}
                size_hint_x: None
                width: root.width - dp(20)
            MDIconButton:
                icon: "brain"
                pos_hint: {'center_x': 0.5, 'center_y': 0.4}
                user_font_size: 64
                on_press: app.root.get_screen('analyzer').analyze(root)
                on_release: app.root.current = 'analyzer'

            # MDRectangleFlatButton:
            #     text: "help"
            #     pos_hint: {'center_x': 0.75, 'center_y': .1}
            #     on_release: app.root.get_screen('main').show_data()


<Analyzer>:
    BoxLayout:
        orientation: 'vertical'
        MDToolbar:
            id: toolbar
            title: "Probably Knot v3"
            md_bg_color: app.theme_cls.accent_color
            right_action_items: [["backburger", lambda x: main.change_screen(root)], ["help-circle-outline", lambda x: app.root.get_screen('main').show_data()]]
        ScrollView:
            MDList:
                id: container

Solution

  • I have been having the same problem, I didn't find the perfect solution, but I found a way to remedy it.

    In place of the right_action_items I used MDFloatActionButton inside the MDToolbar to look like this:

    MDToolbar:
        title: 'Settings'
        elevation: 10
    
        MDFloatingActionButton:
            icon: 'keyboard-backspace'
            theme_text_color: 'Custom'
            elevation: 0
            md_bg_color: app.theme_cls.primary_color
           enter code here on_release: root.ids.screen_manager.current = 'Home'