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.
Related
I am trying to write in a text file after getting an input through TextInput in kivy. The problem is the data gets saved only after i close the app but i want the data to get saved as soon as I leave the specific screen and go to another screen. I am trying to input in add_staff and get it saved in the app through save() function.
import kivymd
import kivy
from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
Builder.load_string('''
<MenuScreen>:
nm:nm_input
BoxLayout:
TextInput:
id:nm_input
Button:
text: 'Add New Staff'
on_press: root.manager.current = 'add_staff'
Button:
text: 'View Staff Profile'
Button:
text: 'Salary report'
<Add_new_staff>:
nam: str(name_input)
job: job_input
GridLayout:
cols: 2
Label:
text: 'Name'
TextInput:
id: name_input
multiline: False
Label:
text: 'Job'
TextInput:
id: job_input
Label:
text: 'Salary'
TextInput:
Label:
text: 'Date of Joining'
TextInput:
Button:
text: 'Back to menu'
on_press: root.manager.current = 'menu'
Button:
text: 'Save'
on_press: root.save(name_input.text, job_input.text);root.manager.current = 'menu'
''')
class MenuScreen(Screen):
pass
class Add_new_staff(Screen):
def save(self, name, job):
fob = open('testi.txt','a')
fob.write(name + "\n")
fob.write(job)
fob.close()
class TestApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(Add_new_staff(name='add_staff'))
return sm
def lo(self,nm):
f=open('log.txt','a')
f.write(nm)
f.close()
if __name__ == '__main__':
TestApp().run()
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: "%"
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()))
I have been started to work in kivy recently. The thing what I am doing now is, i have a blank page with a button, when I click that button it navigates to an user input screen. It works fine, but the content comes in a very small input boxes and text as in the picture.
My question is that I want it bigger and centred.
Here is my code:
In python:
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.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.lang import Builder
class LoginScreen(GridLayout):
def __init__(self, **kwargs):
super(LoginScreen, self).__init__(**kwargs)
self.cols = 2
self.add_widget(Label(text="Username:"))
self.username = TextInput(multiline=False)
self.add_widget(self.username)
self.add_widget(Label(text="Password:"))
self.password = TextInput(multiline=False, password=True)
self.add_widget(self.password)
self.add_widget(Label(text="Two Factor Auth:"))
self.tfa = TextInput(multiline=False)
self.add_widget(self.tfa)
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file("screen.kv")
class SimpleKivy(App):
def build(self):
return presentation
if __name__ == "__main__":
SimpleKivy().run()
In kv:
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition: FadeTransition()
MainScreen:
AnotherScreen:
<MainScreen>:
name: "main"
Button:
color: 0,1,0,1
font_size: 25
size_hint: 0.3,0.2
text: "Click"
on_release: app.root.current = "other"
pos_hint: {"right":1, "top":1}
<AnotherScreen>:
name: "other"
GridLayout:
LoginScreen
In your screen.kv, you have the LoginScreen inside a GridLayout. Since the LoginSCreen is a GridLayout, you do not need that extra GridLayout.
Just change:
<AnotherScreen>:
name: "other"
GridLayout:
LoginScreen
to:
<AnotherScreen>:
name: "other"
LoginScreen:
I have 2 file test.py and test.kv. When I run test.py and pass numeric value in self.abc.text=10 then it gives error
File "/usr/lib/python2.7/dist-packages/kivy/uix/textinput.py", line 2930, in _set_text
text = text.replace(u'\r\n', u'\n')
AttributeError: 'int' object has no attribute 'replace'
If I pass string value then it's working. I think text for string value but I don't what is for numeric value?
test.py
import kivy
kivy.require('1.9.0') # replace with your current kivy version !
import sqlite3 as lite
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.core.window import Window
from kivy.uix.label import Label
#Window.maximize()
from kivy.clock import Clock
from kivy.uix.treeview import TreeView, TreeViewLabel, TreeViewNode
Window.size = (500, 530)
class GroupScreen(Screen):
groupName = ObjectProperty(None)
popup = ObjectProperty(None)
abc = ObjectProperty(None)
def display_groups(self, instance):
self.abc.text=10
class Group(App):
def build(self):
self.root = Builder.load_file('test.kv')
return self.root
if __name__ == '__main__':
Group().run()
test.kv
#:kivy 1.10.0
<CustomLabel#Label>:
text_size: self.size
valign: "middle"
padding_x: 5
<SingleLineTextInput#TextInput>:
multiline: False
<GreenButton#Button>:
background_color: 1, 1, 1, 1
size_hint_y: None
height: self.parent.height * 0.150
GroupScreen:
groupName: groupName
abc:abc
GridLayout:
cols: 2
padding : 30,30
spacing: 10, 10
row_default_height: '40dp'
CustomLabel:
text: 'Number'
SingleLineTextInput:
id: abc
CustomLabel:
text: 'Test'
SingleLineTextInput:
id: groupName
on_text: root.display_groups(self)
GreenButton:
text: 'Ok'
GreenButton:
text: 'Cancel'
Use NumericProperty and then str(root.abc) in kv.
Try this example:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import NumericProperty
class MyBoxLayout(BoxLayout):
abc = NumericProperty(0)
def set_text(self):
self.abc = 42
KV = """
MyBoxLayout:
Button:
text: str(root.abc)
on_release:
root.set_text()
"""
class Testapp(App):
def build(self):
root = Builder.load_string(KV)
return root
Testapp().run()
You need to type self.abc.text = str(rows[1]) in order for it to be passed as the correct type.
Hope this helps!