I am new to Kivy.
When I run the below kivy script on Sublime Text, I get only a Blank Black screen.
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
kivy.require("1.10.1")
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)
class SimpleKivy(App):
def build(self):
return LoginScreen()
if __name__ == "__main__":
SimpleKivy().run()
The __init__() method of LoginScreen is spelled incorrectly. It should be:
def __init__(self, **kwargs):
not:
def __init_(self, **kwargs):
Note the number of underscores.
Related
The app I am creating in Python 3 using Kivy is to teach myself the Hungarian language. When the app loads it simply shows a word in Hungarian and the English translation. What I want to do is when I click the only button (on_press) I need a function to be called and to replace the visible Hungarian word and English translation with a new one.
# hungarian_tutor.py
""" A program to teach Hungarian translated from English """
import kivy
kivy.require("1.11.1")
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.core.audio import SoundLoader
from random import choice
import time
import hungarian_language as hl
class Grid(GridLayout):
def __init__(self, **kwargs):
super(Grid, self).__init__(**kwargs)
self.cols = 1
self.phrase = choice(hl.basics)
self.eng_text = self.phrase[0]
self.hun_text = self.phrase[1]
self.hun_audio = self.phrase[2]
self.add_widget(Label(text="English > {}".format(self.eng_text), font_size=50))
self.add_widget(Label(text="Hungarian > {}".format(self.hun_text), font_size=50))
self.add_widget(Label(text=hl.alphabet, font_size=20))
self.btn1 = Button(text="New Phrase", font_size=40)
self.add_widget(self.btn1)
#self.btn1.bind(on_press=)
class MainApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
return Grid()
if __name__ == "__main__":
MainApp().run()
Thanks in advance
When you use:
self.btn1.bind(on_press=self.pressed)
Then the self.pressed() method should look something like:
def pressed(self, button_instance):
print(button_instance, 'pressed')
I am experimenting with Kivy. When I tried using a screen manager, when the application runs, there is a black screen, nothing appears
That is my code. I have no idea what is the problem. It seems that the GridLayout doesn't get displayed on the screen.
import kivy
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import *
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
class load_file_screen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.my_layout = GridLayout(cols=1)
self.my_layout.cols = 1
self.label = Label(text="Loading files from here")
self.button = Button(text="Click to change")
self.button.bind(on_press=self.changer)
self.my_layout.add_widget(self.label)
self.my_layout.add_widget(self.button)
def changer(self, *args):
self.manager.current = "ViewFile"
class view_file_screen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.my_layout = GridLayout(cols=1)
self.label = Label(text="View File here")
self.button = Button(text="Click to change")
self.button.bind(on_press=self.changer)
self.my_layout.add_widget(self.label)
self.my_layout.add_widget(self.button)
def changer(self, *args):
self.manager.current = "LoadFile"
class my_app(App):
def build(self):
self.my_screen_manger = ScreenManager(transition=SlideTransition())
self.my_screen_manger.add_widget(load_file_screen(name="LoadFile"))
self.my_screen_manger.add_widget(view_file_screen(name="ViewFile"))
# self.my_screen_manger.current = "LoadFile"
return self.my_screen_manger
application = my_app()
application.run()
In both your view_file_screen and your load_file_screen, you need to add the line:
self.add_widget(self.my_layout)
in the __init__() method.
I am writing an app with two screens using ScreenManager. In one screen I have a text input, and a button that reads such text input. If a certain condition from the input is satisfied, the second screen is activated. From this screen, I want to be able to grab the content of the text input from the first screen.
I have made multiple attempts and looked at many similar questions (this one for example), but none of them really seemed to work.
Below is a minimal non-working version of my code:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
class RootWindow(Screen):
def __init__(self, **kwargs):
super(RootWindow, self).__init__(**kwargs)
box = BoxLayout()
self.add_widget(box)
self.searchInput = TextInput(multiline=False)
box.add_widget(self.searchInput)
self.searchButton = Button(text="Search")
self.searchButton.bind(on_press=self.searchRecipe)
box.add_widget(self.searchButton)
def searchRecipe(self, instance):
src = self.searchInput.text
if not src == "Go":
pass
else:
WMan.current = 'result'
class ResultWindow(Screen):
def __init__(self, **kwargs):
super(ResultWindow, self).__init__(**kwargs)
titleBox = BoxLayout()
self.add_widget(titleBox)
print(src)
WMan = ScreenManager()
WMan.add_widget(RootWindow(name='root'))
WMan.add_widget(ResultWindow(name='result'))
class RecipApp(App):
def build(self):
return WMan
if __name__ == "__main__":
RecipApp().run()
If you save a reference to titlebox like this:
class ResultWindow(Screen):
def __init__(self, **kwargs):
super(ResultWindow, self).__init__(**kwargs)
self.titleBox = BoxLayout()
self.add_widget(self.titleBox)
Then you can access the titlebox via the WMan, like this:
def searchRecipe(self, instance):
src = self.searchInput.text
if not src == "Go":
pass
else:
WMan.current = 'result'
WMan.current_screen.titlebox.add_widget(Label(text=src))
I have the following Kivy app and I'm trying to change the text of a Label based on another widget's variable.
I mean, if the variable testing of the class TestApp changes, I want also the value of the variable text of the class TestLabel to change.
To do so, I've created a BooleanProperty in the TestLabel class that points to the testing variable of the TestApp class. The problem is that this callback is never executed despite being changing it each time I press the button.
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import BooleanProperty
Builder.load_string('''
<MainApp>:
orientation: 'horizontal'
rows: 2
TestButton:
text: 'Change value'
on_release: self.change_value()
TestLabel:
''')
class TestLabel(Label):
testing = BooleanProperty()
def __init__(self, **kwargs):
super(TestLabel, self).__init__(**kwargs)
self.app = App.get_running_app()
self.testing = self.app.testing
self.bind(testing=self.changed_value)
def changed_value(self, _instance, newvalue):
self.text = str(newvalue)
class TestButton(Button):
def __init__(self, **kwargs):
super(TestButton, self).__init__(**kwargs)
self.app = App.get_running_app()
def change_value(self):
self.app.testing = not self.app.testing
class MainApp(BoxLayout):
pass
class TestApp(App):
testing = BooleanProperty(False)
def build(self):
return MainApp()
if __name__ == '__main__':
TestApp().run()
It is not necessary to create a testing property in TestLabel since when you do: self.bind(testing = self.changed_value) you are connecting the testing of TestLabel and not the testing of TestApp , so as it never changes testing after the bind then it never gets call the callback.
The bind has to be done using the object that has that property, and in your case the testing belongs to the App, so you must the App.
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import BooleanProperty
Builder.load_string('''
<MainApp>:
orientation: 'horizontal'
rows: 2
TestButton:
text: 'Change value'
on_release: self.change_value()
TestLabel:
''')
class TestLabel(Label):
def __init__(self, **kwargs):
super(TestLabel, self).__init__(**kwargs)
self.app = App.get_running_app()
self.app.bind(testing=self.changed_value)
def changed_value(self, _instance, newvalue):
self.text = str(newvalue)
class TestButton(Button):
def __init__(self, **kwargs):
super(TestButton, self).__init__(**kwargs)
self.app = App.get_running_app()
def change_value(self):
self.app.testing = not self.app.testing
class MainApp(BoxLayout):
pass
class TestApp(App):
testing = BooleanProperty(False)
def build(self):
return MainApp()
if __name__ == '__main__':
TestApp().run()
I'm trying to bind the following function to a Button in Kivy.
def auth(self):
print(self.username)
if self.username == "Hendricko":
print("self.username == Hendricko")
popup = Popup(title="success",
content=Label(text="Howdy !"),
size=(100, 100),
size_hint=(0.3, 0.3),
auto_dismiss=False)
popup.open()
I've tried
class Foo():
def initUI(self):
self.add_widget(Button(text="Auth User and Password", on_press=self.auth))
but this doesn't work. What am I doing wrong?
here is my whole code
from kivy.uix.popup import Popup
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout
class LoginScreen(GridLayout):
def __init__(self, **kwargs):
super(LoginScreen, self).__init__(**kwargs)
self.cols = 2
self.row = 2
self.add_widget(Label(text='User Name'))
self.username = TextInput(multiline=False)
self.add_widget(self.username)
self.add_widget(Label(text='password'))
self.password = TextInput(password=True, multiline=False)
self.add_widget(self.password)
self.hello = Button(text="hello", on_press=self.auth)
self.add_widget(self.hello)
def auth(self):
if self.username == "Hendricko":
popup = Popup(title="success",
content=Label(text="Howdy !"),
size=(100, 100),
size_hint=(0.3, 0.3),
auto_dismiss=False)
popup.open()
class MyApp(App):
def build(self):
return LoginScreen()
if __name__ == '__main__':
MyApp().run()
I don't think any of the answers are very clear. Neither explains that problem is that the callback given to on_press gets called with a parameter, the instance of button, so LoginScreen.auth must accept a parameter after the self:
def auth(self, button):
print('button pressed:', instance)
The problem is not that on_press must be given via Button.bind or that the callback must be a function, it can be a bound method, and the docs cited by other answer and by comments link to ButtonbBhavior which indicates that OP use of on_press in constructor was fine:
self.hello = Button(text="hello", on_press=self.auth)
would have worked if auth had been as described above.
If you read the Button documentation, the key seems to be to use the bind function:
def callback(instance):
print('The button <%s> is being pressed' % instance.text)
btn1 = Button(text='Hello world 1')
btn1.bind(on_press=callback)
Replace line
self.hello = Button(text="hello", on_press=lambda a:self.auth())
of your code and use this :
self.hello = Button(text="hello", on_press=lambda a:self.auth())
Also add below line in auth function to see if its called :)
print "auth called"
and There are many ways to perform a particular task .Above code will be to fix your code in minimum effort , However If you would like to do it in another way . Just use code below .
from kivy.uix.popup import Popup
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout
class LoginScreen(GridLayout):
def __init__(self, **kwargs):
super(LoginScreen, self).__init__(**kwargs)
self.cols = 2
self.row = 2
self.add_widget(Label(text='User Name'))
self.username = TextInput(multiline=False)
self.add_widget(self.username)
self.add_widget(Label(text='password'))
self.password = TextInput(password=True, multiline=False)
self.add_widget(self.password)
self.hello = Button(text="hello")
self.hello.bind(on_press=self.auth)
self.add_widget(self.hello)
def auth(self,instance):
print "auth called"
if self.username == "Hendricko":
popup = Popup(title="success",
content=Label(text="Howdy !"),
size=(100, 100),
size_hint=(0.3, 0.3),
auto_dismiss=False)
popup.open()
class MyApp(App):
def build(self):
return LoginScreen()
if __name__ == '__main__':
MyApp().run()
I report an example of buttons created dynamically within the main class, and then triggered into a single listener:
class allMyApp(TabbedPanel):
def __init__(self, **kwargs):
super(allMyApp, self).__init__(**kwargs)
#[...]
for y in sorted(set(emissionYears)):
btn = Button(text = y,
size_hint_y = None,
height = '48dp',
on_release = lambda btn: self.ids.choseEmissionDate.select(btn.text))
btn.bind(on_press = self.sortByYear)
self.ids.choseEmissionDate.add_widget(btn)
def sortByYear(self, instance):
year = instance.text
print(year)