kivymd Card scroll list items with the help of loop? - python

I am working on a mobile app and I want to create multiple of scoll items by using for loop but whenever I use for loop, gives me some error It has already parent widget. how can I make list of MDCard?
My App:
Click here
My Code:
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.boxlayout import BoxLayout
from kivy.uix.image import AsyncImage
from kivymd.uix.card import MDCard
from kivymd.uix.label import MDLabel
Window.size = (450, 740)
kv = '''
ScreenManager:
Main:
<main>:
name: 'main'
video_list: video_list
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'Video downloader'
ScrollView:
Screen:
id: video_list
'''
class Main(Screen):
pass
sm = ScreenManager()
sm.add_widget(Main(name='main'))
class Ytube(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.theme_cls.colors = 'Red'
self.theme_cls.primary_palette = "Red"
self.root = Builder.load_string(kv)
image = AsyncImage(
source='https://static.hub.91mobiles.com/wp-content/uploads/2020/05/How-to-download-youtube-videos.jpg', size_hint=(1, .7), )
screen_id = self.root.get_screen('main').ids.video_list
for i in range(1):
card = MDCard(orientation='vertical', pos_hint={
'center_x': .5, 'center_y': .7}, size_hint=(.9, .4))
card.add_widget(image)
card.add_widget(MDLabel(
text='Phishing attacks are SCARY easy to do!! (let me show you!)', size_hint=(.6, .2), ))
screen_id.add_widget(card)
def build(self):
return self.root
if __name__ == "__main__":
Ytube().run()
Is there any way to make it
look like this.

The problem is that you are trying to use the same image widget for every MDCard. Any widget can only have one parent. You can only use that image widget once. You can fix that by moving the creation of the image widget inside the loop.
Also, a BoxLayout is a better choice for the child of a ScrollView, since it has a minimum_height property that you can use. Here is a modified version of your code that applies both those suggestions:
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.image import AsyncImage
from kivymd.uix.card import MDCard
from kivymd.uix.label import MDLabel
Window.size = (450, 740)
kv = '''
ScreenManager:
Main:
<main>:
name: 'main'
video_list: video_list
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'Video downloader'
ScrollView:
do_scroll_x: False
BoxLayout:
id: video_list
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
'''
class Main(Screen):
pass
sm = ScreenManager()
sm.add_widget(Main(name='main'))
class Ytube(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.theme_cls.colors = 'Red'
self.theme_cls.primary_palette = "Red"
self.root = Builder.load_string(kv)
screen_id = self.root.get_screen('main').ids.video_list
for i in range(5):
# Make a new image widget for each MDCard
image = AsyncImage(
source='https://static.hub.91mobiles.com/wp-content/uploads/2020/05/How-to-download-youtube-videos.jpg', size_hint=(1, .7), )
card = MDCard(orientation='vertical', pos_hint={
'center_x': .5, 'center_y': .7}, size_hint=(.9, None), height=200)
card.add_widget(image)
card.add_widget(MDLabel(
text='Phishing attacks are SCARY easy to do!! (let me show you!)', size_hint=(.6, .2), ))
screen_id.add_widget(card)
def build(self):
return self.root
if __name__ == "__main__":
Ytube().run()

Related

Kivy: Navigation bar on all screens

I want to keep the Navigationbar on all my screen, I am able to switch screen and display what I want but I don't seem to keep the Navigationbar.
Also for some reason my side menu seems to appear twice, overlapping each other and I'm not sure why, I've tried refactoring the code and it just seems to appear again
Can anyone offer any help?
*.py
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.clock import Clock
from kivy.uix.button import Button
from kivy.core.window import Window
from kivymd.app import MDApp
from kivymd.uix.card import MDCard
from kivymd.uix.label import MDLabel
class FirstWindow(Screen):
pass
class ThirdWindow(Screen):
def on_pre_enter(self):
anchor = AnchorLayout(size=(1,1))
test = "This is the new window"
card = MDCard(orientation='vertical',padding="8dp",size_hint=(1,0.5),pos_hint={'top': 0.1,'right':1},radius=[5, ])
card.test = test
card.add_widget(MDLabel(text=test, halign="center"))
anchor.add_widget(card)
self.anchorID.add_widget(anchor)
class WindowManager(ScreenManager):
pass
class NearMeApp(MDApp):
def build(self):
self.theme_cls.theme_style ="Dark"
self.theme_cls.accent_palette = "Red"
self.theme_cls.primary_palette = "Purple"
self.root = Builder.load_file('NearMe.kv')
if __name__ == '__main__':
NearMeApp().run()
*.kv
#:import hex kivy.utils.get_color_from_hex
#:kivy 1.10.1
WindowManager:
FirstWindow:
ThirdWindow:
<FirstWindow>:
name:"FirstWindow"
Screen:
MDNavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "NearMe Application"
elevation: 10
left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]
Widget:
MDNavigationDrawer:
id: nav_drawer
BoxLayout:
orientation:'vertical'
Button:
text:"ThirdWindow"
on_release: root.manager.current = "ThirdWindow"
<ThirdWindow>:
name:"ThirdWindow"
anchorID:anchorID
AnchorLayout:
id:anchorID
canvas.before:
Color:
rgba: .2, .2, .2, 1
Rectangle:
pos: self.pos
size: self.size
Your md toolbar needs to be above the main windowmanager.
With your mdtoolbar as a child of firstwindow (child of windowmanager), your windowmanager acts on it and the other children of firstwindow at same during change in current window. By moving the mdtoolbar out of firstwindow and above windowmanager the mdtoolbar will remain present.
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.screenmanager import Screen
class FirstWindow(Screen):
pass
class ThirdWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = """
Screen:
MDNavigationDrawer:
id: nav_drawer
BoxLayout:
orientation:'vertical'
Button:
text:"ThirdWindow"
on_release: root.ids.manager.current = "ThirdWindow"
StackLayout:
MDToolbar:
title: "NearMe Application"
size_hint: (1, 0.1)
elevation: 10
left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]
WindowManager:
id: manager
FirstWindow:
ThirdWindow:
<FirstWindow>:
name:"FirstWindow"
Screen:
BoxLayout:
orientation: 'vertical'
Widget:
<ThirdWindow>:
name:"ThirdWindow"
anchorID:anchorID
AnchorLayout:
id:anchorID
canvas.before:
Color:
rgba: .2, .2, .2, 1
Rectangle:
pos: self.pos
size: self.size
"""
class Test(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = Builder.load_string(kv)
def build(self):
return self.screen
the_app = Test()
the_app.run()
The above removes the toolbar from your FirstWindow and places it on its own. In your example the toolbar is a child of FirstWindow so when you change the current window (screen) to ThirdWindow the toolbar disappears with its parent (FirstWindow). Now the toolbar is not a child of either window.

How would I switch screens from a .py file while the screens are managed in a main .kv file?

I have three codes, I am confused with how I would navigate to the next screen in my Organize.kv from my login.py, I have the main kv file that has all the screens saved and the login python and kv file that manages the login screen, the login kv file balances two different tabs, so far I have the create tab that sends you to the create class of the login python file which is connected to mysql, how would I switch screens to the Main Menu which is in the main Organize.kv file from the login python file? Sorry if this doesn't make sense, I'm super warn out from trying to figure this out.
Anything helps, thank you
The main Organize.kv that has all the screens
#:import organize organize
#:import navigation_screen_manager navigation_screen_manager
#:import anchorlayout_with_action_bar anchorlayout_with_action_bar
#:import sharpen_skills sharpen_skills
#:import login login
<MainMenu#BoxLayout>:
orientation: "vertical"
padding: "40dp"
spacing: "20dp"
size_hint: .7, .9
pos_hint: {"center_x": .5}
Button:
text: "Organize"
on_press: app.manager.push("screen2")
Button:
text: "Journal"
on_press: app.manager.push("screen3")
Button:
text: "Sharpen Skills"
on_press: app.manager.push("SkillsExamplesTabs")
Button:
text: "Exit"
on_press: app.stop()
<MyScreenManager>:
Screen:
name: "Login"
title: "login"
LoginTabs:
Screen:
name: "MainMenu"
MainMenu:
Screen:
name: "screen2"
AnchorLayoutWithActionBar:
title: "Organize"
Screen:
name: "screen3"
AnchorLayoutWithActionBar:
title: "Journal"
Screen:
name: "SkillsExamplesTabs"
AnchorLayoutWithActionBar:
title: "Sharpen Skills"
SkillsExamplesTabs:
My login.kv file
<LoginTabs#TabbedPanel>:
do_default_tab: False
TabbedPanelItem:
text: "Create Account"
Create:
TabbedPanelItem:
text: "Login"
Login:
and finally my login.py file
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.stacklayout import StackLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle
import mysql.connector
import navigation_screen_manager
from kivy.uix.screenmanager import ScreenManager, Screen
from navigation_screen_manager import NavigationScreenManager
Builder.load_file("login.kv")
Builder.load_file("Organize.kv")
sm = ScreenManager()
class MyScreenManager(NavigationScreenManager):
pass
class Create(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
self.build()
def build(self):
self.warning = Label(text="", pos_hint={'center_x': .5, 'center_y': .5})
user_label = Label(text="Username", size_hint=(.5, .5),
pos_hint={'center_x': .5, 'center_y': .5})
self.user_textinput = TextInput(text='Enter Username')
pas_label = Label(text="Password", size_hint=(.5, .5),
pos_hint={'center_x': .5, 'center_y': .5})
self.pas_textinput = TextInput(text="enter Password")
enter_button = Button(text="Create")
with user_label.canvas:
Color(0, .25, 1, .25)
enter_button.bind(on_press=self.Add)
self.add_widget(self.warning)
self.add_widget(user_label)
self.add_widget(self.user_textinput)
self.add_widget(pas_label)
self.add_widget(self.pas_textinput)
self.add_widget(enter_button)
def Add(self, btn):
print("Working")
t1 = self.user_textinput.text
t2 = self.pas_textinput.text
print(f"T1 = {t1} and {t2}")
conn = mysql.connector.connect(
user='root',
password='*******',
host='127.0.0.1',
database='Usersdb')
mycursor = conn.cursor()
try:
sql = "INSERT INTO user_info (user_name, user_pass) VALUES (%s, %s)"
val = (t1,t2)
mycursor.execute(sql,val)
conn.commit()
except:
self.warning = "Username Already Taken"
class Login(StackLayout):
pass
And finally my App class
from kivy.app import App
from kivy.uix.label import Label
from kivy.metrics import dp
from kivy.properties import StringProperty, BooleanProperty, ObjectProperty
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.widget import Widget
from navigation_screen_manager import NavigationScreenManager
class MyScreenManager(NavigationScreenManager):
pass
class Organizer(App):
manager = ObjectProperty(None)
def build(self):
self.manager = MyScreenManager()
return self.manager
Organizer().run()
And my Navigation Screen Manager
from kivy.uix.screenmanager import ScreenManager
class NavigationScreenManager(ScreenManager):
screen_stack = []
def push(self, screen_name):
self.screen_stack.append(self.current)
self.transition.direction = "left"
self.current = screen_name
def pop(self):
if len(self.screen_stack) > 0:
screen_name = self.screen_stack[-1]
del self.screen_stack[-1]
self.transition.direction = "right"
self.current = screen_name
Good day. You must access your screen manager in order to set the current screen which is your active screen. In your App class, I recommend saving your screen manager as an attribute via the on_start function.
class MyApp(App):
def on_start(self):
screen_manager = self.root
From there, you could set your current screen using callback methods in kivy or python.
#in kv
on_release: setattr(app.screen_manager, 'current', 'the next screen name')
#in python
def set_screen_callback(self, instance *args):
app.screen_manager.current = "the next screen name"
Your post does not include your App class, so a specific answer is impossible. The fact that you have multiple kv files is irrelevant once those kv files are loaded. In general, you just set the current property of the ScreenManager to the name of the Screen that you want displayed.
Again, the fact that you have multiple kv files is irrelevant once those kv files are loaded. So in any of the kv files, I believe that you should be able to use:
app.manager.push("MainMenu")
or:
app.manager.current = "MainMenu"
to get to the MainMenu Screen.

Scrollview to display different videos in kivy lags after a while

I'm a beginner in kivy and python. I've been trying to create a scrollview in a page that displays selected video on the screen. But after a while when i selected 5-6 videos to display even though i delete the video widget it starts to lag. And i'm open to any suggestions to better way to handle this kind of application.
from kivy.config import Config
Config.set('graphics', 'width', '1920')
Config.set('graphics', 'height', '1080')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.properties import StringProperty
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.uix.button import Button
import os
from kivy.uix.video import Video
from kivy.uix.videoplayer import VideoPlayer
from kivy.clock import mainthread
from functools import partial
from kivy.core.window import Window
Window.clearcolor = (0, 0, 0, 0)
isThereVideo=False
picture_path="/home/linux/kivyFiles/kivyLogin/assets"
video_path="/home/linux/kivyFiles/kivyLogin/videoAssets/"
class Image(Image):
pass
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class Selfie(Screen):
pass
class RootWidget(Widget):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
Clock.schedule_once(self.createMultipleButton)
#mainthread
def createMultipleButton(self, dt):
self.root = Widget()
size_y=150;
size_x=150;
for i in range(1):
folderList = os.listdir(picture_path)
if len(folderList)==0:
time.sleep(1)
break
fileList = os.listdir(picture_path)
print fileList
for file in fileList:
x = (picture_path+"/"+file)
button = Button(id=str(file),text="" + str(file),size_hint=(None, None),height=size_y,width=size_x, pos_hint={'x': 0, 'y': 1},background_normal=x)
button.bind(on_release=partial(self.VideoContainer, file))
print file
self.scrollview.content_layout.add_widget(button)
print button.id
print("Parent of ScreenTwo: {}".format(self.parent))
#print(button.pos)
def VideoContainer(self,name,btn):
global isThereVideo
if isThereVideo==True:
#self.videocontainer.video_layout.unload()
self.videocontainer.clear_widgets()
mylist=name.split('.')
emailButton = Button(id='email')
video = Video(source="/home/linux/kivyFiles/kivyLogin/videoAssets/"+mylist[0]+".mp4", state='play',options={'eos': 'loop'})
video.size=(self.parent.width,self.parent.height)
video_pos=(self.parent.x,self.parent.y)
#video.pos_hint={'x': self.parent.width /2, 'y': self.parent.height/2}
video.play=True
#video.pos=(self.parent.width /2 , self.parent.height/2)
#self.videocontainer.video_layout.add_widget(emailButton)
self.videocontainer.add_widget(emailButton)
emailButton.add_widget(video)
isThereVideo=True
print("Parent of ScreenTwo: {}".format(self.parent))
return 0
class ScreenManagement(ScreenManager):
pass
class VideoContain(Widget):
pass
class ScrollableContainer(ScrollView):
pass
presentation = Builder.load_file("login.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == '__main__':
Window.fullscreen = True
app=MainApp()
app.run()
And my Kv file
ScreenManagement:
MainScreen:
Selfie:
<MainScreen>:
name: 'main'
Button:
on_release: app.root.current = 'selfie'
text: 'Another Screen'
font_size: 50
<Selfie>:
name: 'selfie'
Button:
on_release: app.root.current = 'login'
text: 'Selfie Screen'
font_size: 10
pos_hint: {"right": 1, 'top':1}
size_hint: (0.1, 0.1)
RootWidget:
<RootWidget>
size_hint: (0.1, None)
scrollview: scrollview
videocontainer:videocontainer
size:(self.parent.width, self.parent.height)
VideoContain:
id:videocontainer
##size:(self.parent.width, self.parent.height)
size:(root.width, root.height)
ScrollableContainer:
id: scrollview
size: root.size
pos: root.pos
<VideoContain>
video_layout:video_layout
FloatLayout:
cols:1
id: video_layout
<ScrollableContainer>:
scroll_timeout: 75
scroll_distance: 10
app: app
content_layout: content_layout
GridLayout:
id: content_layout
cols: 1
size_hint: (0.1, None)
pos: root.pos
height: self.minimum_height
padding: 25
spacing: 25
I posted all my code since i don't know which part may causing the problem i'm facing.
Solved it.
def VideoContainer(self,name,btn):
global isThereVideo
if isThereVideo:
# self.videocontainer.video_layout.unload()
self.videocontainer.clear_widgets()
In this part i'm clearing the widgets but i also need to unload the video somehow.
self.video.unload() solved my problem

How to get Python variables to Kivy?

I want to get the random values generated in 'randgen' displayed as text in the button (right now the button displays string). How can I get rand_val into the .kv file?
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.clock import Clock
import random
root = Builder.load_string('''
<Demo>:
cols: 1
BoxLayout:
orientation: 'vertical'
Button:
text: 'rand_val_here'
size_hint: .2, .2
pos_hint: {'x':0, 'center_y': .1}
''')
class Demo(BoxLayout):
pass
class MainApp(App):
def build(self):
Clock.schedule_interval(self.randgen, 0.01)
return Demo()
def randgen(dt, self):
rand_val = random.randint(0, 10)
print(rand_val)
if __name__ == '__main__':
MainApp().run()
The arguments and names of some functions are not correct, I think they are caused because you have tried to copy and remove the secondary part but remember that the order is interesting in python.
If you want to assign a property to a Widget you must first obtain it and for them an id must be placed, this id will be the name of the variable that will be created and assigned, we can access it through ids as I show below:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.clock import Clock
import random
root = Builder.load_string('''
<Demo>:
cols: 1
BoxLayout:
orientation: 'vertical'
Button:
id: btn
size_hint: .2, .2
pos_hint: {'x':0, 'center_y': .1}
''')
class Demo(BoxLayout):
def __init__(self, *args, **kwargs):
BoxLayout.__init__(self, *args, **kwargs)
Clock.schedule_interval(self.randgen, 0.01)
def randgen(self, dt):
rand_val = random.randint(0, 10)
self.ids.btn.text = str(rand_val)
print(rand_val)
class MainApp(App):
def build(self):
return Demo()
if __name__ == '__main__':
MainApp().run()
There are two methods of solving this. The method 1 is using ObjectProperty, and the method 2 is using StringProperty.
Method 1 - Using ObjectProperty
In this example, an ObjectProperty is used to hook up to the button because an id is a weakref to the widget. Using ObjectProperty creates a direct reference, provides faster access and is more explicit.
main.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.clock import Clock
import random
root = Builder.load_string('''
<Demo>:
btn: btn
orientation: 'vertical'
Button:
id: btn
text: 'rand_val_here'
size_hint: .2, .2
pos_hint: {'x':0, 'center_y': .1}
''')
class Demo(BoxLayout):
btn = ObjectProperty(None)
def __init__(self, **kwargs):
super(Demo, self).__init__(**kwargs)
Clock.schedule_interval(self.randgen, 0.01)
def randgen(self, dt):
self.btn.text = str(random.randint(0, 10))
class MainApp(App):
title = "Updating Button's Text - Using ObjectProperty"
def build(self):
return Demo()
if __name__ == '__main__':
MainApp().run()
Output
Method 2 - Using StringProperty
Without changing much of your original app, the solution is as follow:
Since your root widget class, Demo is a BoxLayout, therefore the attribute cols: 1 which is only applicable to GridLayout is not required in the kv file
Declare rand_val of type StringProperty
Populate the button's text using app.rand_val
Note:
Your app has nested BoxLayout.
main.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.lang import Builder
from kivy.clock import Clock
import random
root = Builder.load_string('''
<Demo>:
BoxLayout:
orientation: 'vertical'
Button:
text: app.rand_val
size_hint: .2, .2
pos_hint: {'x':0, 'center_y': .1}
''')
class Demo(BoxLayout):
pass
class MainApp(App):
rand_val = StringProperty("")
def build(self):
Clock.schedule_interval(self.randgen, 0.01)
return Demo()
def randgen(self, dt):
self.rand_val = str(random.randint(0, 10))
print(self.rand_val)
if __name__ == '__main__':
MainApp().run()
Output

Changing kivy widget properties within Class

I'm having difficulty figuring out how to change the text of a label within a kivy widget. For simplicity, I have a label set to 0 and I would like to change the text to read 30 in this example. However, I get the following error.
AttributeError: 'super' object has no attribute 'getattr'
I understand that I'm probably not properly targeting that widget and I am hoping someone can please explain how to specifically reference the text of this label (self.ids.mainel1temp.stuff_r.text = '30') to update (with more detail than fixing the code)
#!/usr/bin/kivy
import kivy
from random import random
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.switch import Switch
from kivy.uix.label import Label
from kivy.config import Config
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '480')
Builder.load_string("""
<Menuscreen>:
#Handling the gesture event.
ScreenManager:
id: manager
Screen:
id: main_screen
name:'main_screen'
stuff_r: mainel1temp
FloatLayout:
Label:
id: mainel1temp
size: self.texture_size
text:'0'
size_hint: None, None
text_size: 75,75
pos: 295,308
font_size:'20sp'
halign: 'center'
""")
class Thermostuff(Screen):
stuff_r = ObjectProperty(None)
def starttherm(self):
Clock.schedule_interval((self.read_temp), 1)
def read_temp(self, dt):
self.ids.mainel1temp.stuff_r.text = '30'
Thermrun = Thermostuff()
Thermrun.starttherm()
class MenuScreen(Screen):
pass
sm = ScreenManager()
menu_screen = MenuScreen(name='menu')
sm.add_widget(menu_screen)
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
You do a couple of things wrong here.
You dont want to put a ScreenManager inside a Screen
Only one ScreenManager is needed.
Then you can start the Clock in the __init__ of the Thermostuff(Screen)
Or if you want it to initiate on_enter you need to overrite that. In that case you might want to check somehow, if its allready started, so you wont have multiple clocks running.
Then when you create an ObjectProperty you dont need self.ids, because you allready created that property. So self.stuff_r is now the label.
I rewrote your example a bit, to demonstrate this.
Try this:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty
from kivy.clock import Clock
sm = """
#Handling the gesture event.
ScreenManager:
id: manager
MenuScreen:
Button:
text: "Go to Thermostuff"
on_release:
root.current = "main_screen"
Thermostuff:
name:'main_screen'
stuff_r: mainel1temp
FloatLayout:
Label:
id: mainel1temp
size: self.texture_size
text:'0'
size_hint: None, None
text_size: 75,75
pos: 295,308
font_size:'20sp'
halign: 'center'
"""
class Thermostuff(Screen):
stuff_r = ObjectProperty(None)
test_temp = 0
def __init__(self,**kwargs):
super(Thermostuff,self).__init__(**kwargs)
Clock.schedule_interval((self.read_temp), 1)
def read_temp(self, dt):
self.test_temp += 1
self.stuff_r.text = str(self.test_temp)
class MenuScreen(Screen):
pass
class TestApp(App):
def build(self):
return Builder.load_string(sm)
if __name__ == '__main__':
TestApp().run()

Categories