I'm trying to setup a day and month display.
In the planner.kv file I can't get the Telldate child widget to work with pos_hint in FloatLayout but it seems to be working fine with Button.
I'm not sure if i've set up FloatLayout properly or if I'm going about it in the wrong way.
I understand that Telldate is a custom widget and a child widget when inside FloatLayout unless I'm wrong about that.
Everything else is working as intended
main.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from time import strftime
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
class Telldate(Widget):
todayday = ObjectProperty('')
def __init__(self,*args, **kwargs):
super().__init__(*args, **kwargs)
self.todayday= strftime('%A')
class PlannerApp(App):
pass
if __name__ == '__main__':
PlannerApp().run()
planner.kv
<Telldate>:
Button:
size:(50,50)
text:self.parent.todayday
FloatLayout:
Button:
text: 'ay'
size_hint:(None,None)
pos_hint: { 'x': 0.5, 'y': 0.8}
Telldate:
size_hint:(None,None)
pos_hint: { 'x': 0.5, 'y': 0.8}
I'm using python V3.6.2 and Kivy v1.10.0 with IDLE V3.6.2
Thanks for your patience!
----Edit1:---
using
class Telldate(FloatLayout):
instead of
class Telldate(Widget):
allows me to set hint_size because i'm now inheriting FloatLayout properties and not widget properties but still doesn't allow hint_pos to be set.
The rest of the code is still the same.
So what I learnt was that widgets don't inherit properties of layouts which is where my troubles began with Telldate(Widget), i found this in the documentations for widget.
Using Telldate(FloatLayout) instead and calling(not sure if the right terminology) the class Telldate via <Telldate> into kivy solved my issue.
And then creating FloatLayout for whenever I want to call a custom widget as in the .kv file
planner.kv
<Tellday#Label>:
size:(50,50)
<Telldate>:
FloatLayout:
Tellday:
size_hint:( None,None)
text: self.parent.parent.todayday
pos_hint:{'top': 0.5,'right':0.5}
main.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from time import strftime
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.lang import Builder
class Telldate(FloatLayout):
todayday= ObjectProperty('')
# todaymonth = ObjectProperty('')
def __init__(self,*args, **kwargs):
super().__init__(*args, **kwargs)
self.todayday=strftime('%A')
self.todayday= strftime('%A')
# self.todaymonth= strftime('%b')
class PlannerApp(App):
def build(self):
return Telldate()
if __name__ == '__main__':
PlannerApp().run()
hope this helps someone!
Related
in KivyMD there is a module or something called "Boxshadow", I need it to use almost every widget which uses levitation and i couldn't find anything resolving this issue. I am just a beginner with Kivy and KivyMD especially therefore I would be truly thankful for a solution. I as well cant follow simple tutorials because something does not work for me which works for them.
The simplest Application:
from kivymd.app import MDApp
from kivymd.uix.screen import MDScreen
from kivymd.uix.button import MDRectangleFlatButton
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.config import Config
import kivy
from kivy.core.window import Window
Window.size = (200, 425)
class MainApp(MDApp):
def build(self):
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "DeepPurple"
return Builder.load_file('Mainapplication.kv')
MainApp().run()
Kivy:
MDScreen:
MDRaisedButton:
text: "Knopf"
pos_hint: { "center_x": 0.5, "center_y": 0.8}
ERROR Raised:
File "C:\KivyMD\virtual\lib\site-packages\kivy\factory.py", line 147, in __getattr__
raise FactoryException('Unknown class <%s>' % name)
kivy.factory.FactoryException: Unknown class <BoxShadow>
I'm trying to create a simple login page for this app using Kivy.
I'm new to this, and I'm wondering how I can connect the Email TextInput to a variable (email_catch) in my python code, similar to a normal .get() function.
Python Code
from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, StringProperty
class Login_Window(Screen):
def verify(self):
email_catch = self.root.ids.email.text
print(email_catch)
class MyApp(App):
def build(self):
return Login_Window()
if __name__ == "__main__":
MyApp().run()
.KV File
#:kivy 2.0.0
<Login_Window>:
GridLayout:
cols:1
size: root.width, root.height
GridLayout:
cols:2
Label:
text: 'Email'
TextInput:
multiline: False
id: email
Button:
text: 'Log In'
on_press: root.verify()
Since you are calling root in verify method of Login_Window class (where it (root) hasn't been defined yet) and not in the build method of the App class you are supposed to get an AttributeError .
In order to access an id within that class you should use self.ids. So the change you need:
def verify(self):
email_catch = self.ids.email.text
print(email_catch)
I'm using Kivy for a user interface to a control application. As such, the UI is subsidiary to the essential functionality. For modularity/tidyness, I've been trying to place all the Kivy code in a separate source file and to call it as the last step in Main.
However, if I do this, I find that some things don't work properly (for example, creating labels programatically and updating their text by scheduled events).
Is this something which should be possible?
Is there a 'trick' of which I should be aware?
If the detail of my question is not clear, I can put up some test code to illustrate.
Monolithic code, which works as expected:
cat test.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.properties import StringProperty
from kivy.clock import Clock
import random
Builder.load_string('''
<YourWidget>:
BoxLayout:
id: Box1
size: root.size
Button:
id: button1
text: "Change text"
on_release: root.change_text()
''')
class YourWidget(Screen):
random_number = StringProperty()
def __init__(self, **kwargs):
super(YourWidget, self).__init__(**kwargs)
label = Label(
id= 'label1',
text = self.random_number
)
self.ids.Box1.add_widget(label)
self.random_number = 'ini'
Clock.schedule_interval(self.change_text,1)
def change_text(self, *largs):
self.random_number = str(random.randint(1, 100))
class updatetestapp(App):
def build(self):
sm = ScreenManager(transition=NoTransition())
sm.add_widget(YourWidget(name='d_analogs'))
return YourWidget()
if (True):
updatetestapp().run()
If I then attempt to modularise my code, placing all the Kivy processing in a user function,everything works except the display of the ransom number variable. The variable persists through successive callbacks, as shown by calls to print, but it simply doesn't display. I'm guessing that this is something to do with the scope or context of the variable - Kivy isn't displaying the same variable which is being updated in the callback.
cat Main.py
#from mytest import mytest
import threading
import time
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.properties import StringProperty
from kivy.clock import Clock
from display import *
def main():
Display()
if __name__ == "__main__":
main()
cat display.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.properties import StringProperty
from kivy.clock import Clock
import random
Builder.load_string('''
<YourWidget>:
BoxLayout:
id: Box1
size: root.size
Button:
id: button1
text: "Change text"
on_release: root.change_text()
''')
class YourWidget(Screen):
random_number = StringProperty()
def __init__(self, **kwargs):
super(YourWidget, self).__init__(**kwargs)
label = Label(
id= 'label1',
text = self.random_number
)
self.ids.Box1.add_widget(label)
self.random_number = 'ini'
Clock.schedule_interval(self.change_text,1)
def change_text(self, *largs):
self.random_number = str(random.randint(1, 100))
class test(App):
def build(self):
sm = ScreenManager(transition=NoTransition())
sm.add_widget(YourWidget(name='d_analogs'))
return YourWidget()
def Display():
test().run()
You don't have any code that would change the text of your Label. Although you update self.random_number, you don't update the Label's text property, therefore you don't see any change.
I am new to Kivy language. I am trying build a simple program to switch between two screens. First screen with contain a button which on_release it will switch to second screen. On clicking the button on second screen will get to first screen.
Issues i face:
1. Button is placed on the corner and i am expecting its size to be full window but it small
On click and release the button doesnt' show any effect.
Chat.kv
<ChatGUI>:
MainManager:
MainWindow:
SecondWindow:
<MainWindow>:
name: "main"
Button:
text:"to second window"
on_release:app.root.current="second"
<SecondWindow>:
name: "second"
Button:
text:"back to main"
on_release:app.root.current="main"
python code:
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.graphics import Rectangle, Color, Canvas
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.core.window import Window
from kivy.config import Config
from kivy.lang import Builder
class ChatGUI(Widget):
present=Builder.load_file("Chat.kv")
class MainWindow(Screen):
pass
class SecondWindow(Screen):
pass
class MainManager(ScreenManager):
pass
class ChatApp(App):
def build(self):
return ChatGUI()
if __name__=="__main__":
ChatApp().run()
My output# i am not able to add image so posted link of output
I am practicing from youtube tutorial.
I have checked many codes from stack overflow and i don't see issues in my code.
output should display button of size occupying whole window and on_release it should switch to next screen.
Can you let me know what could be issue.
You do not need to add a ScreenManager inside a Widget.
So
class ChatGUI (ScreenManager):
in python file and
<ChatGUI>:
MainWindow:
SecondWindow:
in kv file
that's all I changed to make your example work.
Chat.kv
<ChatGUI>:
MainWindow:
SecondWindow:
<MainWindow>:
name: "main"
Button:
text:"to second window"
on_release:app.root.current="second"
<SecondWindow>:
name: "second"
Button:
text:"back to main"
on_release:app.root.current="main"
main.py
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.graphics import Rectangle, Color, Canvas
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.core.window import Window
from kivy.config import Config
from kivy.lang import Builder
class ChatGUI(ScreenManager):
present=Builder.load_file("Chat.kv")
class MainWindow(Screen):
pass
class SecondWindow(Screen):
pass
class ChatApp(App):
def build(self):
return ChatGUI()
if __name__=="__main__":
ChatApp().run()
Problem 1 - widget # bottom left hand corner & not full window?
Button is placed on the corner and i am expecting its size to be full
window but it small
Root Cause
The Button widget appeared on the bottom left hand corner because the root is a Widget and no position (pos, or pos_hint) was provided. Therefore, the default position of (0, 0) was used.
The size is not a full window because by default the size of a Widget is (100 x 100) or the default size_hint is (1, 1).
Kivy Widget » Default values
A Widget is not a Layout: it will not change the position or the size of its children. If you want control over positioning or
sizing, use a Layout.
The default size of a widget is (100, 100). This is only changed if the parent is a Layout. For example, if you add a Label inside a
Button, the label will not inherit the button’s size or position
because the button is not a Layout: it’s just another Widget.
The default size_hint is (1, 1). If the parent is a Layout, then the widget size will be the parent layout’s size.
Problem 2 - on release button screen not switched?
On click and release the button doesnt' show any effect.
Root Cause
The screen was not switched when button press was released, because the root of the App is not a ScreenManager.
Solution
There are two options to the problems.
Option 1 - use Layout as root
This option use BoxLayout as the root and requires the following enhancements. A Layout can be a GridLayout, BoxLayout, FloatLayout, etc.
Py file
Replace Widget with BoxLayout
Replace present = Builder.load_file(...) with Builder.load_file(...)
Move Builder.load_file(...) out of class ChatGUI() and add pass
kv file
Add id: sm under instantiated object, MainManager:
Replace app.root.current with app.root.ids.sm.current
Snippets - Option 1
main1.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
Builder.load_file("main1.kv")
class ChatGUI(BoxLayout):
pass
class MainWindow(Screen):
pass
class SecondWindow(Screen):
pass
class MainManager(ScreenManager):
pass
class ChatApp(App):
def build(self):
return ChatGUI()
if __name__ == "__main__":
ChatApp().run()
main1.kv
<ChatGUI>:
MainManager:
id: sm
MainWindow:
SecondWindow:
<MainWindow>:
name: "main"
Button:
text: "to second window"
on_release: app.root.ids.sm.current="second"
<SecondWindow>:
name: "second"
Button:
text: "back to main"
on_release: app.root.ids.sm.current="main"
Option 2 - use ScreenManager as root
This option requires the following enhancements:
Py file
Remove import statement, from kivy.uix.widget import Widget
Remove class ChatGUI()
Replace return ChatGUI() with return MainManager()
Replace present = Builder.load_file(...) with Builder.load_file(...)
kv file
Remove class rule, : in the kv file
Replace MainManager: with class rule, :
Snippets - Option 2
main2.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
Builder.load_file("main2.kv")
class MainWindow(Screen):
pass
class SecondWindow(Screen):
pass
class MainManager(ScreenManager):
pass
class ChatApp(App):
def build(self):
return MainManager()
if __name__ == "__main__":
ChatApp().run()
main2.kv
<MainManager>:
MainWindow:
SecondWindow:
<MainWindow>:
name: "main"
Button:
text: "to second window"
on_release: app.root.current="second"
<SecondWindow>:
name: "second"
Button:
text: "back to main"
on_release: app.root.current="main"
I am attempting to construct a screen with a VERTICAL splitter to separate content; however, I am unsuccessful in identifying a solution even after consulting the kivy docs and looking through the related questions here.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.splitter import Splitter
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.properties import StringProperty, DictProperty
from kivy.uix.screenmanager import ScreenManager, Screen
kv = '''
ScreenManagement:
id: 'manager'
MainScreen:
name: 'main'
manager: 'manager'
<MainScreen>:
BoxLayout:
orientation: 'vertical'
Button:
text: 'New'
Splitter:
sizeable_from: 'top'
Button:
text: 'test'
'''
class ScreenManagement(ScreenManager):
pass
class MainScreen(Screen):
pass
class MyApp(App):
def build(self):
return Builder.load_string(kv)
MyApp().run()
Here is what I am current seeing with this code
As you can see, the splitter is beside the second button rather than between the buttons horizontally; and when the splitter is activated, it shrinks the button horizontally rather than vertically. How do I change the code for the effect that I desire?
Simple misspelling. sizeable_from should be sizable_from.