i tried to show a plot in second screen after i clicked the button in the first screen.
this is the code that i tried.
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg
from kivy.uix.widget import Widget
from pandas import read_excel
import matplotlib.pyplot as plt
plt.plot([1, 23, 2, 4])
plt.ylabel('some numbers')
class MainWindow(Screen):
def btn(self):
print("name: ",self.name2.text)
self.ids.destination.add_widget(FigureCanvasKivyAgg(plt.gcf()))
class SecondWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file("my.kv")
class MyMainApp(App):
def build(self):
return kv
if __name__=="__main__":
MyMainApp().run()
#:kivy 1.9.1
WindowManager:
MainWindow:
SecondWindow:
<MainWindow>:
name: "main"
name2: name2
GridLayout:
cols:1
size: root.width, root.height
GridLayout:
cols:2
Label:
text:"name: "
TextInput:
id: name
multinline:False
Label:
text:"name2: "
TextInput:
id: name2
multinline:False
Button:
text:"Submit"
on_release:
root.btn()
app.root.current = "second"
root.manager.transition.direction = "left"
<SecondWindow>:
name: "second"
GridLayout:
cols:1
BoxLayout:
id: destination
Button:
text: "Go Back"
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
but i got error says 'super' object has no attribute '__getattr__' and i don't know what it means. please help me.
The problem is that you are trying to use an id that is defined in a different Screen. The destination is defined in SecondWindow, so MainWindow knows nothing about it. So, you can reference that id by going through SecondWindow like this:
class MainWindow(Screen):
def btn(self):
print("name: ",self.name2.text)
self.manager.get_screen('second').ids.destination.add_widget(FigureCanvasKivyAgg(plt.gcf()))
Related
I'm trying to add these two screens to the screenmanager but i'm getting this error. What am i doing wrong? I know there are other ways to use the screen manager but i want to know how i could use it with the builder method with these seperate kv files.
The codes that i wrote for the screens:
Python
from kivy.uix.screenmanager import Screen
class Screen2(Screen):
def buttFunc2(self):
print("Screen2")
from kivy.uix.screenmanager import Screen
class Screen1(Screen):
def buttFunc(self):
print("Screen1")
KV
<Screen2>:
name: "screen2"
BoxLayout:
Button:
text: "Screen 2"
on_release: root.buttFunc2()
Button:
text: "Go To Screen1"
#on_release: i also want this function to change the screen to the other one
<Screen1>:
name: "screen1"
BoxLayout:
Button:
text: "Screen 1"
on_release: root.buttFunc()
Button:
text: "Go To Screen2"
#on_release: i also want this function to change the screen to the other one
Main.py Python file:
from kivy.core.window import Window
from kivy.lang.builder import Builder
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager
from screen1 import Screen1
class MyApplication(MDApp):
def build(self):
Window.size = 300,600
sm = ScreenManager()
sm.add_widget(Builder.load_file("screen1.kv"))
sm.add_widget(Builder.load_file("screen1.kv"))
return sm
if __name__ == "__main__":
MyApplication().run()
I also would like to go between screens by a button but i dont't know how to do it using these files.
Need to import custom Screen classes just like other scripts:
main.py:
from kivy.core.window import Window
from kivy.lang.builder import Builder
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager,Screen
from sc1 import Screen1
from sc2 import Screen2
class MyApplication(MDApp):
def build(self):
Window.size = 300, 600
sm = ScreenManager()
sm.add_widget(Screen1())
sm.add_widget(Screen2())
return sm
if __name__ == "__main__":
MyApplication().run()
sc1.py:
from kivy.uix.screenmanager import Screen
from kivy.lang.builder import Builder
class Screen1(Screen):
Builder.load_file('screen1.kv')
def buttFunc(self):
print("Screen1")
sc2.py:
from kivy.uix.screenmanager import Screen
from kivy.lang.builder import Builder
class Screen2(Screen):
Builder.load_file('screen2.kv')
def buttFunc2(self):
print("Screen2")
screen1.kv:
<Screen1>:
name: "screen1"
BoxLayout:
Button:
text: "Screen 1"
on_release: root.buttFunc()
Button:
text: "Go To Screen2"
on_release: app.get_running_app().root.current = 'screen2'
screen2.kv:
<Screen2>:
name: "screen2"
BoxLayout:
Button:
text: "Screen 2"
on_release: root.buttFunc2()
Button:
text: "Go To Screen1"
on_release: app.get_running_app().root.current = 'screen1'
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.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.button import Button
Window.size = (500,700)
Builder.load_file('calc.kv')
class MyLayout(Widget):
pass
class App(App):
def build(self):
return MyLayout()
if __name__ == "__main__":
App().run()
this is my calc.py please help me to solve the problem
#:kivy 2.0.0
BoxLayout:
orientation:"vertical"
size: root.width, root.height
TextInput:
id: clac_input
text: "0"
halign: "right"
font_size : 65
size_hint: (1, .15)
GridLayout:
cols:4
rows:5
Button:
size_hint: (.2, .2)
font_size: 32
text: "%"
this is my calc.kv
From what I'm seeing the app is not returning any screens for your widgets to show on. I've changed a bit of your code to what I believe is correct that solves the issue.
.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
from kivy.uix.button import Button
Window.size = (500,700)
Builder.load_file('calc.kv')
class MyLayout(Widget):
pass
class Screen1(Screen):
pass
class WindowManager(ScreenManager):
pass
class App(App):
def build(self):
return WindowManager()
if __name__ == "__main__":
App().run()
calc.kv
<WindowManager>:
Screen1
<Screen1>:
BoxLayout:
orientation:"vertical"
size: root.width, root.height
GridLayout:
cols:4
rows:5
TextInput:
id: clac_input
text: "0"
halign: "right"
font_size : 65
size_hint: (1, .15)
Button:
size_hint: (.2, .2)
font_size: 32
text: "%"
Hey i am new to kivy and i make a really basic Kivy program following step by step Tech with tim video tutorial about Kivy but for some reason in my computer the is an error with the from kivy.properties import ObjectProperty and i found that one solution is to change the from "kivy.properties import ObjectProperty" to "import kivy.properties as kyprops" and then type kyprops anytime i need to declare ObjectProperty but i am still getting this 2 errors " in class MyGrid(Widget): " and " in MyGrid name = kyprops(None) TypeError: 'module' object is not callable" Any ideas ? here is the code
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.widget import Widget
import kivy.properties as kyprops
class MyGrid(Widget):
name = kyprops.ObjectProperty(None)
email = kyprops.ObjectProperty(None)
def btn(self):
print("Name:", self.name.text, "email:", self.email.text)
self.name.text = ""
self.email.text = ""
class MyApp(App):
def build(self):
return MyGrid()
if __name__ == "__main__":
MyApp().run()
and the Kv code is this
#:kivy !ex
<MyGrid>:
name: name
email: email
GridLayout:
cols:1
size: root.width - 200, root.height -200
pos: 100, 100
GridLayout:
cols:2
Label:
text: "Name: "
TextInput:
id: name
multiline:False
Label:
text: "Email: "
TextInput:
id: email
multiline:False
Button:
text:"Submit"
on_press: root.btn()
Remove from your kv, the line:
#:kivy !ex
That is not a legal kivy version specification.
I am new to Kivy. I want my Label to be on the left side, however it stays always in the centre, what I'm doing wrong?
.py
`
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.label import Label
class Display(BoxLayout):
pass
class Screen_One(Screen):
pass
class Screen_Two(Screen):
pass
class Screen_Three(Screen):
pass
class DemoApp(App):
icon = 'icon.png'
title = 'control panel'
def build(self):
return Display()
if __name__ == '__main__':
DemoApp().run()
Here is a litte snippet of the .kv file.
<Screen_Two>:
name: 'screen_two'
# BoxLayout:
AnchorLayout:
anchor_x: 'left'
anchor_y: 'top'
Label:
text: 'test box position'
Thanks for any answer that is usefull.
The problem is that the default size for a child widget is to fill its parent, so your anchor_x and anchor_y have no effect. To fix it, just set the size of your Label to something reasonable:
<Screen_Two>:
name: 'screen_two'
AnchorLayout:
anchor_x: 'left'
anchor_y: 'top'
Label:
text: 'test box position'
size_hint: (None, None)
size: self.texture_size