Display widget when the user wants to in kivy - python

it is a simple program but i can not find a way to make it work. i just want to add a widget in boxlayout2 when the user presses the button (and has not writed anything in textinput) which is located in boxlayout1 .The widget do not display in screen.What should i do?
main.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
class BoxLayout1(BoxLayout):
def Search(self):
if self.ids.textinput.text!='':
BoxLayout2()
class BoxLayout2(BoxLayout):
def Print(self):
self.add_widget(Button(text='hello'))
class TestApp(App):
pass
TestApp().run()
and here is my kivy code
test.kv
<BoxLayout1>:
BoxLayout:
Label:
text:'Hello'
TextInput:
id: textinput
Button:
text: 'write'
on_press: root.Search()
BoxLayout:
orientation: 'vertical'
BoxLayout1:
BoxLayout2:
I see the presentation layout i want but the button is nowhere to be found.

To make it clear let's follow the stream of the app you've written.
it creates a BoxLayout and puts BoxLayout1 and BoxLayout2 in it, the second one doesn't have any content. When you click on write, the app checks the content of the text box and if valid, calls the constructor of BoxLayout2! Now at this point it creates an instance of this class, but does not keep it's reference so it will be discarded immediately. Now what you want is to call a function of a currently existing instance, not to create another one. Here's the code:
python:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
class BoxLayout1(BoxLayout):
def Search(self):
if self.ids.textinput.text!='':
self.parent.ids.bxl2.addButton()
# BoxLayout2()
class BoxLayout2(BoxLayout):
def addButton(self):
button=Button(text='hello')
self.add_widget(button)
kivy language:
<BoxLayout1>:
BoxLayout:
Label:
text:'Hello'
TextInput:
id: textinput
Button:
text: 'write'
on_press: root.Search()
BoxLayout:
orientation: 'vertical'
BoxLayout1:
BoxLayout2:
id:bxl2

Related

Scroll view in Kivy is not scrolling, How could a fix this?

I want to be able to scroll within the buttons numbered 10-1 but it wont let me scroll. Any solutions? I was finally able to put the buttons in a scrollview but after all my effort I am not able to move it. It just crams into the space provided and doesn't move at all.
orientation: "vertical"
SongText:
size_hint: 1,0.35
PausePlay:
size_hint: 1,0.1
ScrollView:
orientation: "vertical"
PlayList:
orientation: "vertical"
AddDeleteShuffle:
size_hint: 1,0.2
<SongText>:
Label:
id: songtitle
text: "Song Title"
<PausePlay>:
Button:
id: play
text: "Play"
Button:
id: pause
text: "Pause"
This is the main area of focus I think nothing is needed here but who knows.
<PlayList>: #Main area of conceren
<AddDeleteShuffle>:
BoxLayout:
Button:
text: "Shuffle"
Button:
text: "Delete"
Button:
text: "Shuffle"
kv file ^
py file
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.stacklayout import StackLayout
from kivy.uix.gridlayout import GridLayout
from kivy.metrics import dp
from kivy.core.audio import SoundLoader
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.screenmanager import ScreenManager, Screen
class AddDeleteShuffle(BoxLayout):
pass
class PlayList(BoxLayout):
def __init__(self,**kwargs):
super().__init__(**kwargs)
for i in range(0,10):
size = dp(100)
b = Button(text=str(i+1), size_hint=(1,None), size=(size,size))
self.add_widget(b)
Class for the playlist it is inside a scroll view, but I can't move it. Maybe I have to add a layout in the kv file. I have no idea.
class PausePlay(BoxLayout):
pass
class SongText(BoxLayout):
pass
class AppLayout(BoxLayout):
pass
class Sound5App(App):
def build(self):
return AppLayout()
if __name__ == "__main__":
Sound5App().run()

Kivy On pressing a Button, a New Button is created which takes to Second Screen

I have a code where there are two Screens: "Main" & "Second", when you press a button in the Main Screen a new button is created in the same screen. I need the new button created to take me to the Second Screen. Please Help as I need it for a bigger project soon.
Normal Code:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import Screen,ScreenManager
class Main(Screen):
pass
class Second(Screen):
pass
class Manager(ScreenManager):
pass
kv=Builder.load_file("test1.kv")
movie=Manager()
movie.add_widget(Main(name="main"))
movie.add_widget(Second(name="second"))
class Movie(App):
def build(self):
return movie
Movie().run()
Kv Code:
#: import Button kivy.uix.button.Button
<Main>:
name: "main"
GridLayout:
id: GL
cols: 1
size_hint: (.5,.5)
pos_hint: {"center_x":.5,"center_y":.5}
Button:
text: "Press Me"
on_press:
Btn=Button(text="Second",size_hint=(.5,.5),pos_hint= {"center_x":.5,"center_y":.5})
GL.add_widget(Btn)
#Btn.bind(on_press= ????)
<Second>:
name: "second"
Button:
text: "Go Back!"
size_hint: (.5,.5)
pos_hint: {"center_x":.5,"center_y":.5}
on_press:
app.root.current="main"
The simplest way is to just define a method in the Main class that does the Screen change:
class Main(Screen):
def switch(self, button_instance):
self.manager.current = 'second'
Then reference that method in the kv:
Button:
text: "Press Me"
on_press:
Btn=Button(text="Second",size_hint=(.5,.5),pos_hint= {"center_x":.5,"center_y":.5}, on_press=root.switch)
GL.add_widget(Btn)
A more complex approach that doesn't require any additional methods works by using the python setattr() method to set the current Screen of the ScreenManager:
Button:
text: "Press Me"
on_press:
Btn=Button(text="Second",size_hint=(.5,.5),pos_hint= {"center_x":.5,"center_y":.5})
Btn.bind(on_press=lambda ins: partial(setattr, root.manager, 'current', 'second')())
GL.add_widget(Btn)
The lambda is required to avoid passing the Button instance to the setattr() method. Also, an import is required for partial in the kv:
#: import partial functools.partial

Python 3.7, Change button's colour when it's down

How do I change the button's color when it's down? As in, when you press the button, replace the blue-ish colour into another one?
I've tried fiddling around with background_color_down, background_color_normal, I tried using canvas and the sort but nothing seems to have the effect I intend it to
Or you could try giving the path to a png file with your design of the pressed button to the background_down attribute. Here my file is called "pressed.png" and is located within the same folder as the python programm. this is a link to something i made within 30 seconds in inkscape.
#!/usr/bin/python3.5
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang.builder import Builder
from kivy.properties import ObjectProperty, ListProperty
from kivy.atlas import Atlas
kv= Builder.load_string('''
<MainScreen>
my_but:my_but
orientation: "vertical"
size_hint:1,1
# size_hint: 0.3,0.3
# pos_hint:{"center_x": 1, "center_y":1}
Label:
size_hint: 0.5,0.4
text: "Look at my Button go:"
Button:
id:my_but
size_hint: 0.5,0.4
text: "klick me"
# background_normal: ""
background_down: "pressed.png"
''')
class MainScreen(BoxLayout):
my_but = ObjectProperty(None)
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
class myApp(App):
def build(self):
return MainScreen()
if __name__ == "__main__":
myApp().run()

Kivy: How to refernce kv ID in Python?

I'm new to Kivy and I would have to think this is possible, but I can't figure it out - How can I update a Kivy label when a button is pressed, but only by referencing that Kivy id within Python? (The reason I'm trying to do it this way is because in my actual application, I would like several labels to update at once, which I was hoping I could do all within the button_pressed equivalent button I have in my app).
In the simple example below, I'm just trying to have the button pressed and then have the label update to 'Updated!'
Thanks very much!
My Python code:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
import random
class TestingWidget(BoxLayout):
# This is the kv id of the Label I would like to update
label_to_update = StringProperty('')
# This is the action I would like to happen when the button is pressed
def button_pressed(self):
label_to_update.text = 'Updated!'
class TestButtonApp(App):
def build(self):
return TestingWidget()
if __name__ == '__main__':
TestButtonApp().run()
My kv file:
<TestingWidget>:
BoxLayout:
orientation: 'horizontal'
Button:
text: 'test'
on_press: root.button_pressed()
Label:
id: label_to_update
text: 'Trying to get this to update'
You definitely update all label when you press the button. Just crate a StringProperty for each and do what you are doing now.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
from kivy.lang import Builder #used because I didn't want to create two files
import random
Builder.load_string('''
<TestingWidget>:
BoxLayout:
orientation: 'horizontal'
Button:
text: 'test'
on_press: root.button_pressed()
Label:
id: label_to_update
text: root.label_to_update
''')
class TestingWidget(BoxLayout):
# This is the kv id of the Label I would like to update
label_to_update = StringProperty('Trying to get this to update')
#default text set
# This is the action I would like to happen when the button is pressed
def button_pressed(self):
self.label_to_update = 'Updated!'
class TestButtonApp(App):
def build(self):
return TestingWidget()
if __name__ == '__main__':
TestButtonApp().run()

Return ID of button when clicked Kivy Python

Simple problem I'm having:
When I click a button in my Kivy/Python app, I want to gain access to the ID of that button.
# Kivy code
Button:
id: position_1
on_press: app.access_button_id()
I have had various trial and error attempts but I cannot figure it out. The button is nested as follows (as part of a bigger app), if this is a factor in my problem:
FloatLayout:
AnchorLayout:
ScreenManager:
Screen:
BoxLayout:
FloatLayout:
Button:
id: position_1
on_press: app.access_button_id()
Here is my Python code, which returns all of the id's. That's as close as I have got:
# Python code
def access_button_id(name):
print(self.root.ids)
The problem I've got is that I don't even know what I should be looking at in the documentation as I do not fully understand the terminology yet, so I can't find the right information to learn from.
EDIT:
The (name) passed into the function is for some other functionality, not related to this problem.
You already know the id - you set it yourself. These are mostly used as a hard-coded values in your code:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
Builder.load_string('''
<MyWidget>:
Button:
id: id_value_1
text: 'Print my id'
on_press: print({'id_value_1': self.proxy_ref})
Button:
id: id_value_2
text: 'Print all ids'
on_press: print(root.ids)
''')
class MyWidget(BoxLayout):
pass
class MyApp(App):
def build(self):
widget = MyWidget()
print({'id_value_1': widget.ids['id_value_1']})
return widget
if __name__ == '__main__':
MyApp().run()
Why do you need id of a Button if you already have an access to it? What are you trying to accomplish?
EDIT
An example solution to problem mentioned in the comment:
import random
import functools
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.lang import Builder
Builder.load_string('''
<MyWidget>:
Button:
text: 'B1'
on_press: root.open_popup(self)
Button:
text: 'B2'
on_press: root.open_popup(self)
''')
class MyWidget(BoxLayout):
def open_popup(self, caller):
fun = functools.partial(self.rename, caller)
popup = Popup(
title='Test popup',
content=Button(
text='rename',
on_press=fun
),
size_hint=(None, None), size=(400, 400)
)
popup.open()
def rename(self, caller, *args):
caller.text = ''.join(chr(random.randint(48, 90)) for i in range(5))
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
MyApp().run()

Categories

Resources