I'm a beginner and would like to insert an MDSpinner while executing a loop, or a mysql query, or some process that takes time. I made this example below to illustrate my problem:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.clock import Clock
import threading
KV = '''
MDScreen:
ScreenManager:
id: screen_manager
MDScreen:
name: 'a'
BoxLayout:
orientation: 'vertical'
MDLabel:
text: 'test - screen a'
pos_hint: {"center_x": .5, "center_y": .5}
Button:
id: btn
text: 'screen a'
size_hint: 0.5, 0.1
pos_hint: {"center_x": .5, "center_y": .5}
on_press:
load.active = True
app.aperta()
MDScreen:
name: 'b'
BoxLayout:
orientation: 'vertical'
MDLabel:
text: 'test - screen b'
pos_hint: {"center_x": .5}
Button:
id: btn2
text: 'screen b'
size_hint: 0.5, 0.5
pos_hint: {"center_x": .5, "center_y": .5}
MDSpinner:
id: load
active: False
size: dp(64), dp(64)
size_hint: None, None
pos_hint: {'center_x': 0.5, "center_y": .5}
'''
class Example(MDApp):
def build(self):
self.tela = Builder.load_string(KV)
return self.tela
def aperta(self):
threading.Thread(target=self.op_1).start()
def op_1(self, *args):
cont = 0
while cont < 1000000:
cont += 1
print(cont)
self.tela.ids.load.active = False
self.tela.ids.screen_manager.current = 'b'
Example().run()
however, when I change the screen, the following error appears and all the elements of the two screens overlap...
TypeError: Cannot change graphics instruction outside the main Kivy thread
You can also use the mainthread decorator, which is the equivalent to what #ApuCoder suggested:
class Example(MDApp):
def build(self):
self.tela = Builder.load_string(KV)
return self.tela
def aperta(self):
threading.Thread(target=self.op_1).start()
def op_1(self, *args):
cont = 0
while cont < 1000000:
cont += 1
print(cont)
self.go_to_b()
#mainthread
def go_to_b(self):
self.tela.ids.load.active = False
self.tela.ids.screen_manager.current = 'b'
Related
I'm making a kivy app to find the rhyming words for a word entered by the user. It displays all the rhyming words as OneLineListItems in an MDList which is inside a kivy RecycleView. On clicking on one of these OneLineListItems it displays the definition of the word on the right-hand side of the screen. However, when I click on a OneLineListItem its definition takes very long to appear and sometimes it lags so badly that the app closes. Am I doing something wrong or is it just my computer? Code below:
from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.label import MDLabel
from kivymd.uix.list import OneLineListItem
import pronouncing
import enchant
from PyDictionary import PyDictionary
dictionary = PyDictionary()
d = enchant.Dict("en_US")
kv = """
Screen:
input:input
scroll:scroll
word:word
defs:defs
MDGridLayout:
rows: 1
cols: 2
MDGridLayout:
rows: 2
cols: 1
MDFloatLayout:
MDTextField:
id:input
size_hint: (.4, None)
height: 26
multiline: False
on_text_validate: app.rhyme()
hint_text: "Search"
mode: "rectangle"
pos_hint: {"center_x": .25, "center_y": .85}
font_name: "DejaVuSans.ttf"
text_size: self.size
MDFloatLayout:
RecycleView:
size_hint: 0.85,1.5
bar_width: dp(15)
bar_height: dp(40)
scroll_type: ["content"]
pos_hint: {"center_x": 0.45, "center_y": 0.93}
MDList:
id: scroll
MDBoxLayout:
id:defs
orientation: "vertical"
md_bg_color: 0, 1, 0.2, 1
MDLabel:
id: word
text: ""
text_size: self.size
"""
class RhymeApp(MDApp):
played = []
x_turn = True
def build(self):
self.screen = Builder.load_string(kv)
return self.screen
def rhyme(self):
raw_rhymes = pronouncing.rhymes(self.screen.input.text)
rhymes = []
[rhymes.append(x) for x in raw_rhymes if x not in rhymes and x[-1] != "." and d.check(x)]
self.screen.scroll.clear_widgets()
for i in rhymes:
self.screen.scroll.add_widget(
OneLineListItem(text=f"{i}".capitalize(), on_release=self.dictionary)
)
def dictionary(self, btn):
nl = '\n'
self.screen.defs.clear_widgets()
self.screen.word.text = btn.text.capitalize()
meaning = dictionary.meaning(btn.text, disable_errors=True)
if meaning is None:
self.screen.defs.add_widget(
MDLabel(text=f"Sorry, no meaning for that word.",
text_size="self.size")
)
else:
for key in meaning:
self.screen.defs.add_widget(
MDLabel(text=f"Part of speech: {key} {nl}Meaning: {nl}{nl}{meaning[key][0].capitalize()}.",
text_size="self.size")
)
if __name__ == "__main__":
RhymeApp().run()
Can someone please help?
First create a custom class for the data-class like following:
class ListItem(OneLineListItem):
# Here define all the necessary attrs., methods apart from the defaults (if you need any).
Now in your .kv initialize RecycleView as,
RecycleView:
id: scroll
#size_hint: 0.85,1.5
bar_width: dp(15)
bar_height: dp(40)
scroll_type: ["content"]
#pos_hint: {"center_x": 0.45, "center_y": 0.93}
viewclass: "ListItem"
RecycleBoxLayout:
default_size: None, dp(48)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Now you are ready to feed RecycleView with you data as,
def rhyme(self):
...
self.screen.ids.scroll.data = [
{"text" : f"{i}".capitalize()}
for i in rhymes]
I'm trying to learn Kivy. Most stuff works when I just code it separate. But when I combine like MultiScreen with other code I always strugle.
Here I want that after closing the DatePicker to change the Text(id: date_label. Same code worked without the MultiScreen
Error: line 31, in on_cancel
self.root.ids.date_label.text = "Cancel"
AttributeError: 'CreateScreen' object has no attribute 'root'
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.uix.picker import MDDatePicker
Window.size = (350, 600)
class MenuScreen(Screen):
def input_user(self):
global username_1
username_1 = self.userinput.text
print(username_1)
class MainScreen(Screen):
def user_name(self):
print(username_1)
class CreateScreen(Screen):
# Click Ok
def on_save(self, instance, value, date_range):
print(instance, value, date_range)
# Click Close
def on_cancel(self, instance, value): # HERE IS THE ERROR
self.root.ids.date_label.text = "Cancel"
def show_date_picker(self):
date_dialog = MDDatePicker()
date_dialog.bind(on_save=self.on_save, on_cancel=self.on_cancel)
date_dialog.open()
sm = ScreenManager()
sm.add_widget(MenuScreen(name="menu"))
sm.add_widget(MainScreen(name="main-screen"))
sm.add_widget(CreateScreen(name="create-screen"))
class MyApp(MDApp):
def build(self):
screen = (Builder.load_file("kvfile.kv"))
return screen
if __name__ == '__main__':
MyApp().run()
KV File
ScreenManager:
MenuScreen:
MainScreen:
CreateScreen:
<MenuScreen>:
userinput: input
name: "menu"
BoxLayout:
padding: "50dp"
MDTextField:
id: input
padding: "10dp"
hint_text: "Enter Username"
pos_hint: {"center_x": 0.5, "center_y": 0.6}
MDRectangleFlatButton:
text: "Continue"
pos_hint: {"center_x": 0.5, "center_y":0.5}
on_release: root.manager.current = "main_screen"
on_press: root.input_user()
<MainScreen>:
name: "main_screen"
MDLabel:
text: "Welcome"
halign: "center"
pos_hint: {"center_x": 0.5, "center_y": 0.9}
MDRectangleFlatButton:
text: "Back"
pos_hint: {"center_x": 0.5, "center_y":0.2}
on_press: root.manager.current = "menu"
MDRectangleFlatButton:
text: "Print"
pos_hint: {"center_x": 0.5, "center_y":0.6}
on_release: root.manager.current = "create_screen"
MDRectangleFlatButton:
text: "Empty"
pos_hint: {"center_x": 0.5, "center_y":0.4}
on_press: root.manager.current = "menu"
<CreateScreen>
name: "create_screen"
MDRaisedButton:
text: "Date"
pos_hint: {"center_x": 0.5, "center_y" : 0.5}
on_release: root.show_date_picker()
MDLabel:
id: date_label
text: "Select Date"
pos_hint: {"center_x": 1, "center_y" : 0.4}
Thank you
The error is telling you that 'CreateScreen' object has no attribute 'root'. You are trying to refer to root in the line:
self.root.ids.date_label.text = "Cancel"
In that line, self is the instance of CreateScreen, so self.root is trying to access a root attribute of self (CreateScreen). If you are trying to access the ids of CreateScreen, then just use:
self.ids.date_label.text = "Cancel"
I'm pretty new to Python and even more new to Kivy. My goal is to make a timer which I can set beforehand (which later shall control the GPIOs of my Raspberry, but that's another topic). I'm not really sure how I can do that. This ist my code so far:
Python Code: (Left away most imports for more cleanness)
import Global
Builder.load_file("screens.kv")
class ScreenOne(Screen):
pass
class ScreenTwo(Screen):
pass
class ScreenThree(Screen):
def pressPlus(self):
Global.DTIME = Global.DTIME + 0.5
self.ids.lbl1.text = str(Global.DTIME) + "h"
def pressMinus(self):
if Global.DTIME > 0:
Global.DTIME = Global.DTIME - 0.5
else:
pass
self.ids.lbl1.text = str(Global.DTIME) + "h"
def showTime(self):
self.ids.lbl1.text = str(Global.DTIME) + "h"
def printTime(self):
app = App.get_running_app()
print(app.TIME)
class Manager(ScreenManager):
screen_one = ObjectProperty(None)
screen_two = ObjectProperty(None)
screen_three = ObjectProperty(None)
class Trockner(App):
def build(self):
m = Manager(transition=WipeTransition())
return m
def furz(self, *args):
print("Fuuuuurz")
Trockner().run()
.kv File:
<ScreenOne>:
Button:
text: "Manuell"
on_press:
root.manager.current = 'screen2'
app.furz()
size_hint: 0.15, 0.15
pos_hint: {'center_x': 0.075, 'center_y': 0.9225}
Button:
text: "Zeiteingabe"
on_press:
root.manager.current = 'screen3'
size_hint: 0.15, 0.15
pos_hint: {'center_x': 0.25, 'center_y': 0.9225}
Label:
#text: "Eingestellte Zeit: "
id: lbl1
size_hint: 0.15, 0.15
pos_hint: {'center_x': 0.5, 'center_y': 0.9225}
<ScreenTwo>:
Button:
text: "Automatik"
on_press: root.manager.current = 'screen1'
size: 100, 100
size_hint: None, None
pos_hint: {'center_x': 0.075, 'center_y': 0.9}
<ScreenThree>:
FloatLayout:
Label:
id: lbl1
size_hint:[.5,.5]
pos_hint: {'right':1, 'top':1}
font_size: 100
Button:
text: "+"
size_hint:[.5,.5]
on_press:
root.pressPlus()
Button:
text: "-"
size_hint:[.5,.5]
pos_hint: {'right': 1}
on_press:
root.pressMinus()
Button:
text: "Enter"
size_hint:[.5,.5]
pos_hint: {'top':1, 'left':1}
on_press:
root.manager.current = 'screen1'
<Manager>:
id: screen_manager
screen_one: screen_one
screen_two: screen_two
screen_three: screen_three
ScreenOne:
id: screen_one
name: 'screen1'
manager: screen_manager
ScreenTwo:
id: screen_two
name: 'screen2'
manager: screen_manager
ScreenThree:
id: screen_three
name: 'screen3'
manager: screen_manager
Right now, the Global.py which I'm importing is only holding the DTIME variable, so I can access it from Python and Kivy.
Plan is, that on Screen Three I can set a time which is then used on screen one again to start my countdown timer from set time. I also have to have access to the set time from my python code to switch the GPIOs after said time. The timer progress should also be visible on screen one then, which probably works with Kivy clock and animation. But I'm not really sure about that either, so help would be very much appreciated!
I've some problems with multiple MDLabels in BoxLayout (that is contains by AnchorLayout), so all the MDLabel objects are stacked in one place on the screen!
I dont know how to make them centered and grouped like a list (with spacing and e.g.)
Please, help me with solving that problem!
Thanks a lot and sorry for bad english.
There is my main.py
from kivy.app import App
from kivymd.theming import ThemeManager
from kivymd.label import MDLabel
from kivy.uix.screenmanager import Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.metrics import dp, sp, pt
def toast(text):
from kivymd.toast.kivytoast import toast
toast(text)
class MyScreen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.menu_items = [
{
"viewclass": "MDMenuItem",
"text": "text%d" % i,
"callback": self.callback,
}
for i in range(1, 3)
]
self.menu_button = None
def change_variable(self, value):
print("\nvalue=", value)
self.VARIABLE = value
print("\tself.VARIABLE=", self.VARIABLE)
def callback(self, *args):
toast(args[0])
class MainApp(App):
title = "KivyMD MDDropdownMenu Demo"
theme_cls = ThemeManager()
def build(self):
return MyScreen()
if __name__ == "__main__":
MainApp().run()
And there is my main.kv file contains:
#:import MDDropdownMenu kivymd.menus.MDDropdownMenu
#:import MDRaisedButton kivymd.button.MDRaisedButton
#:import MDLabel kivymd.label.MDLabel
<MDMenuItem>:
on_release:
app.root.change_variable(self.text)
app.root.menu_button.text = self.text
<MyScreen>:
name: 'myscrn'
AnchorLayout:
anchor_y: 'center'
BoxLayout:
orientation: 'vertical'
size_hint: 0.1, 0.5
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
spacing: dp(10)
MDRaisedButton:
id: mainbutton
size_hint: None, None
size: 3 * dp(48), dp(48)
text: 'MDButton1'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
opposite_colors: True
on_release:
root.menu_button = mainbutton
MDDropdownMenu(items=root.menu_items, width_mult=4).open(self)
MDRaisedButton:
id: secondbutton
size_hint: None, None
size: 3 * dp(48), dp(48)
text: 'MDButton2'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
opposite_colors: True
on_release:
root.menu_button = secondbutton
MDDropdownMenu(items=root.menu_items, width_mult=4).open(self)
AnchorLayout:
anchor_y: 'top'
BoxLayout:
orientation: 'vertical'
size_hint: 0.95, 0.5
padding: [0, 0, 0, 0]
spacing: dp(5)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
MDLabel:
font_size: dp(12)
text: '123'
MDLabel:
font_size: dp(22)
text: '456'
Woops, looks like a simple mistake. Your indentation on KV Lang is incorrect. You didn't nest your labels into BoxLayout correctly.
AnchorLayout:
anchor_y: 'top'
BoxLayout:
orientation: 'vertical'
size_hint: 0.95, 0.5
padding: [0, 0, 0, 0]
spacing: dp(5)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
MDLabel:
font_size: dp(12)
text: '123'
MDLabel:
font_size: dp(22)
text: '456'"""
I have a kivy app I built, that receives a message from a server, saves it into a text file, and displays the text file onto the screen. However, the text always exceeds the ScrollView widget and goes onto some other widgets like the picture below.
Is there any ways to solve this? Any help will be appreciated. Thank You.
This is my code:
#Todo: fix line 334 AttributeError
#Remove the upload button also
#Error Fixed
#Todo: fix message received exceeds border error
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivymd.dialog import MDDialog
from kivymd.theming import ThemeManager
from kivymd.navigationdrawer import NavigationLayout
from kivymd.list import OneLineAvatarListItem, ILeftBody
from kivymd.toast import toast
from kivymd.dialog import MDDialog
from kivy.uix.popup import Popup
from threading import Thread
import socket
sock = socket.socket()
sock.connect(('127.0.0.1', 6818))
sock.sendall(b"add_contact hello llo")
sock = socket.socket()
sock.connect(('127.0.0.1', 6818))
sock.sendall(b'new llo')
class MyLayout(BoxLayout):
scr_mngr = ObjectProperty(None)
def check_data_login(self):
username = self.scr_mngr.screen1.username.text
password = self.scr_mngr.screen1.password.text
print(username)
print(password)
if username == "KivyMD" and password == "kivy":
self.ids["wrongpass"].text = ""
self.change_screen("screen2")
else:
self.ids["wrongpass"].text = "Wrong username or password, please try again"
def change_screen(self, screen, *args):
self.scr_mngr.transition.direction = 'left'
self.scr_mngr.current = screen
def back_to_chat(self):
self.scr_mngr.transition.direction = 'right'
self.scr_mngr.current = 'screen2'
class nav_layout(NavigationLayout):
def print_text(self):
print('hello')
def check_data_login(self):
username = self.ids.screen1.username.text
password = self.ids.screen1.password.text
print(username)
print(password)
if username == "KivyMD" and password == "kivy":
Thread(target=self.recover_data).start()
self.change_screen("screen2")
self.ids.wrongpass.text = ""
else:
self.ids.wrongpass.text = \
"Wrong username or password, please try again"
def recover_data(self):
print('started')
while True:
data = sock.recv(1024)
data = data.decode()
if data:
print(data)
data = data.split()
data = data[-1] + ": " + ' '.join(data[:-1])
r = data + '\n'
open('chat1.txt', 'a+').write(r)#Fix The the Attribute Error that occurs when a message is sent!!!!!
e = open('chat1.txt', 'r').readlines()
self.ids.Chat_String.text = '\n\r'.join(e)
print(data)
def change_screen(self, screen, *args):
self.ids.scr_mngr.transition.direction = 'left'
self.ids.scr_mngr.current = screen
def back_to_chat(self):
self.ids.scr_mngr.transition.direction = 'right'
self.ids.scr_mngr.current = 'screen2'
def logout(self):
# logout function, returns to screen 1
self.ids.scr_mngr.current = 'screen1'
class UploadPopup(Popup):
def load(self, path, selection):
print(path, selection)
KV = """
#:import Toolbar kivymd.toolbar.Toolbar
#:import MDNavigationDrawer kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerDivider kivymd.navigationdrawer.NavigationDrawerDivider
#:import NavigationDrawerToolbar kivymd.navigationdrawer.NavigationDrawerToolbar
#:import MDTextField kivymd.textfields.MDTextField
#:import MDSeparator kivymd.card.MDSeparator
#:import MDThemePicker kivymd.theme_picker.MDThemePicker
#:import CardTransition kivy.uix.screenmanager.CardTransition
#:import Factory kivy.factory.Factory
<MDCustomIconItem>:
text: root.text
AvatarSampleWidget:
source: root.icon
<UploadPopup>:
id: popup
title: "Upload"
BoxLayout:
FileChooserIconView:
id: FileChoose
pos_hint_x: 0.5
pos_hint_y: 0.5
on_selection: root.load(FileChoose.path, FileChoose.selection)
MDRaisedButton:
text: "Upload"
text_color: (0,0,0,1)
on_release: root.load(FileChoose.path, FileChoose.selection)
on_release: popup.dismiss()
MDRaisedButton:
text: "Close"
text_color: (0,0,0,1)
on_release: popup.dismiss()
nav_layout:
id: nav_layout
MDNavigationDrawer:
id: nav_drawer
drawer_logo: 'logo.png'
NavigationDrawerToolbar:
title: 'hello'
NavigationDrawerIconButton:
icon: 'settings'
text: 'Account Settings'
on_release: root.change_screen('screen3')
NavigationDrawerIconButton:
icon: 'face'
text: 'Friends'
on_release: root.print_text()
NavigationDrawerIconButton:
icon: 'logout'
text: 'Logout'
on_release: root.logout()
NavigationDrawerDivider:
height: dp(1)
MyLayout:
scr_mngr: scr_mngr
orientation: 'vertical'
ScreenManager:
transition: CardTransition()
id: scr_mngr
screen1: screen1
Screen:
id: screen1
name: 'screen1'
username: username
password: password
BoxLayout:
size_hint: None, None
size: dp(520), dp(340)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
BoxLayout:
orientation:'vertical'
padding: dp(20)
spacing:20
MDLabel:
text: 'Chat App'
theme_text_color: 'Secondary'
font_style:"Title"
size_hint_y: None
height: dp(36)
MDSeparator:
height: dp(1)
MDTextField:
id: username
hint_text: "Username "
size_hint_y: 0.9
helper_text_mode: "on_focus"
MDTextField:
id: password
hint_text: "Password "
helper_text_mode: "on_focus"
size_hint_y: 0.9
password: True
MDFlatButton:
text: "Login"
pos_hint: {'center_x': 0.5}
on_release: root.check_data_login()
MDLabel:
id: wrongpass
color: 1,0,1,1
text: ""
Screen:
name: 'screen2'
id: screen2
Toolbar:
id: toolbar
title: "Welcome ! "
pos_hint: {'center_x': 0.5, 'center_y': 0.96}
md_bg_color: app.theme_cls.primary_color
background_palette: 'DeepPurple'
background_hue: 'A400'
left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer() ]]
right_action_items: [['animation', lambda x: MDThemePicker().open()], ['camera', lambda x: print('hello')]]
MDLabel:
id: data
font_style: 'Title'
theme_text_color: 'Primary'
text: "Data :"
height: self.texture_size[1] + dp(3)
halign: 'center'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
Screen:
name: 'screen3'
id: screen3
Toolbar:
id: tools
title: "Your Profile"
pos_hint: {'center_x': 0.5, 'center_y': 0.96}
md_bg_color: app.theme_cls.primary_color
background_palette: 'DeepPurple'
background_hue: 'A400'
left_action_items: [['arrow-left', lambda x: root.back_to_chat()]]
MDLabel:
id: Profile_String
font_size: 90
text: "XXX"
halign: 'center'
pos_hint: {'center_x': 0.5, 'center_y': 0.85}
Screen:
name: 'screen4'
id: screen4
Toolbar:
id: tools
title: "XXX"
pos_hint: {'center_x': 0.5, 'center_y': 0.96}
md_bg_color: app.theme_cls.primary_color
background_palette: 'DeepPurple'
background_hue: 'A400'
left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer() ]]
right_action_items: [['animation', lambda x: MDThemePicker().open()], ['camera', lambda x: print('hello')]]
ScrollView:
pos_hint: {'center_x': .55, 'y': .35}
MDLabel:
size_hint: 1, None
id: Chat_String
font_size: 40
text: "XXX"
MDTextField:
id: Input_String
hint_text: 'Enter Your Message...'
helper_text_mode: 'on_focus'
pos_hint: {'center_x': 0.35, 'center_y': 0.2}
size_hint_x: 0.6
multiline: True
MDRaisedButton:
id: Send_Button
text: 'Send'
pos_hint: {'center_x': 0.75, 'center_y': 0.2}
MDRaisedButton:
id: Choose_Image
text: 'Attach File'
pos_hint: {'center_x': 0.9, 'center_y': 0.2}
on_release: Factory.UploadPopup().open()
"""
class MDCustomIconItem(OneLineAvatarListItem):
icon = StringProperty('')
text = StringProperty()
def _set_active(self, active, list):
pass
class AvatarSampleWidget(ILeftBody, Image):
pass
class MyApp(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Blue'
title = "Navigation Drawer"
main_widget = None
def __getattr__(self, attr):
return super().__getattr__(attr)
def build(self):
self.main_widget = Builder.load_string(KV)
return self.main_widget
def callback(self, instance, value):
self.main_widget.ids.scr_mngr.current = 'screen4'
def on_start(self):
for i in range(15):
self.main_widget.ids.nav_drawer.add_widget(
MDCustomIconItem(
text="Item menu %d" % i,
icon='logo.png',
on_release=lambda x, y=i: self.callback(x, y)))
MyApp().run()
You need to set the size of the ScrollView. Add size_hint: (0.85, 0.55)
Snippets
ScrollView:
size_hint: (0.85, 0.55)
pos_hint: {'center_x': .55, 'y': .35}
MDLabel:
id: Chat_String
font_size: 40
Output