Reputation:
App is made with Python 3.9.5
, Kivy 2.0.0rc4
and KivyMD 0.104.2
. I made KivyMD
button. With it you can toggle dark/light mode. But it's printing out error and idk why. I mean, it works for this other guy who helped me on this. But it doesn't work for me. I played around with it a little bit and I've managed to toggle dark/light mode only on this MainWidget class. I want to toggle on the entire app. Here's my Kivy
code:
<MainWidget>:
MDScreen:
id: screenId
md_bg_color: 0, 0, 0, 1
MDIconButton:
id: light_mode
icon: "brightness-4"
user_font_size: "64sp"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
on_press: app.presser()
And here's my Python
code:
class MainWidget(MDFloatLayout):
pass
class MyApp(MDApp):
pressed = False
def build(self):
self.theme_cls.theme_style = "Dark"
self.screen_manager = ScreenManager()
self.mainwidget = MainWidget()
screen = Screen(name='First')
screen.add_widget(self.mainwidget)
self.screen_manager.add_widget(screen)
def presser(self):
if self.pressed:
self.root.ids.light_mode.text_color = 0, 0, 0, 1
self.root.ids.screenId.md_bg_color = 1, 1, 1, 1
self.pressed = not self.pressed
else:
self.root.ids.light_mode.text_color = 1, 1, 1, 1
self.root.ids.screenId.md_bg_color = 0, 0, 0, 1
self.pressed = not self.pressed
And here's the error
:
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\guram\Desktop\WordBondV.2\main.py", line 815, in <module>
myapp.run()
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\app.py", line 950, in run
runTouchApp()
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\base.py", line 582, in runTouchApp
EventLoop.mainloop()
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\base.py", line 347, in mainloop
self.idle()
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\base.py", line 391, in idle
self.dispatch_input()
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\base.py", line 342, in dispatch_input
post_dispatch_input(*pop(0))
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\base.py", line 248, in post_dispatch_input
listener.dispatch('on_motion', etype, me)
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\core\window\__init__.py", line 1412, in on_motion
self.dispatch('on_touch_down', me)
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\core\window\__init__.py", line 1428, in on_touch_down
if w.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\uix\screenmanager.py", line 1198, in on_touch_down
return super(ScreenManager, self).on_touch_down(touch)
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\uix\relativelayout.py", line 297, in on_touch_down
ret = super(RelativeLayout, self).on_touch_down(touch)
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivymd\uix\behaviors\ripple_behavior.py", line 255, in on_touch_down
super().on_touch_down(touch)
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivymd\uix\button.py", line 969, in on_touch_down
return super().on_touch_down(touch)
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\uix\behaviors\button.py", line 151, in on_touch_down
self.dispatch('on_press')
File "kivy\_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
File "kivy\_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
File "kivy\_event.pyx", line 1132, in kivy._event.EventObservers._dispatch
File "C:\Users\guram\Desktop\WordBondV.2\venv\lib\site-packages\kivy\lang\builder.py", line 57, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Users\guram\Desktop\WordBondV.2\my.kv", line 32, in <module>
on_press: app.presser()
File "C:\Users\guram\Desktop\WordBondV.2\main.py", line 810, in presser
self.root.ids.light_mode.text_color = 1, 1, 1, 1
File "kivy\properties.pyx", line 864, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
Upvotes: 1
Views: 443
Reputation: 46
There are So Many Errors In Your Code
Don't Worry i solved it for you ;)
Here is the Corrected code :)
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivymd.app import MDApp
kv = """
<MainWidget>:
screenId: screenId
light_mode: light_mode
MDFloatLayout:
MDScreen:
id: screenId
md_bg_color: 0, 0, 0, 1
MDIconButton:
id: light_mode
icon: "brightness-4"
user_font_size: "64sp"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
on_press: root.presser()
"""
Builder.load_string(kv)
sm = ScreenManager()
class MainWidget(Screen):
pressed = False
screenId = ObjectProperty(None)
light_mode = ObjectProperty(None)
def presser(self):
if self.pressed:
self.light_mode.text_color = 0, 0, 0, 1
self.screenId.md_bg_color = 1, 1, 1, 1
self.pressed = not self.pressed
else:
self.light_mode.text_color = 1, 1, 1, 1
self.screenId.md_bg_color = 0, 0, 0, 1
self.pressed = not self.pressed
class MyApp(MDApp):
def build(self):
self.theme_cls.theme_style = "Dark"
sm.add_widget(MainWidget(name="First"))
return sm
MyApp().run()
You don't need to use root.ids.widgetid
always!
You can define the widget as global widget in your kivy file so that it can be accessed in your python file by using ObjectProperty
Also the best practice is to define all the methods which belong to the specific class in your root class itself :)
Upvotes: 0
Reputation: 141
I'd recommend keeping your root widget inside the kv
code so that you can traverse through available id
in ids
dict. In your code, it's unable to find those id
s.
Here's a working version of your code:
I've merged both kivy and python codes in one file but you can obv. separate them and later load your kivy file using Builder.load_file(kivy_file_name)
from kivymd.app import MDApp
from kivymd.uix.floatlayout import MDFloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
kv="""
ScreenManager:
Screen:
name: 'First'
MainWidget:
id: my_widget
<MainWidget>:
MDScreen:
id: screenId
md_bg_color: 0, 0, 0, 1
MDIconButton:
id: light_mode
icon: "brightness-4"
user_font_size: "64sp"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
on_press: app.presser()
"""
class MainWidget(MDFloatLayout):
pass
class MyApp(MDApp):
pressed = False
def build(self):
self.theme_cls.theme_style = "Dark"
self.screen_manager = Builder.load_string(kv) # ScreenManager()
#self.mainwidget = MainWidget()
#screen = Screen(name='First')
#screen.add_widget(self.mainwidget)
#self.screen_manager.add_widget(screen)
return self.screen_manager
def presser(self):
if self.pressed:
self.root.ids.my_widget.ids.light_mode.text_color = 0, 0, 0, 1
self.root.ids.my_widget.ids.screenId.md_bg_color = 1, 1, 1, 1
self.pressed = not self.pressed
else:
self.root.ids.my_widget.ids.light_mode.text_color = 1, 1, 1, 1
self.root.ids.my_widget.ids.screenId.md_bg_color = 0, 0, 0, 1
self.pressed = not self.pressed
if __name__ == '__main__':
MyApp().run()
Upvotes: 1