I am new to kivy and try to grasp the concept behind the kivy language. I try to have a button that changes its background picture on click. With my current code, I get no Errors, but the button doesn't do anything if I try to click it...
This is my code:
<ScatterTextWidget>:
orientation: 'vertical'
my_picture: 'picture.png'
Button:
id: b1
canvas.after:
Rectangle:
id: m_r
source: root.my_picture
pos: self.pos
size: self.size
on_release: root.nextPicture()
.py:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
class ScatterTextWidget(FloatLayout):
def nextPicture(self):
self.ids.my_picture = 'newPicture.png'
self.canvas.ask_update()
return
class GuiApp(App):
def build(self):
return ScatterTextWidget()
if __name__ == "__main__":
GuiApp().run()
What do I have to do to make my button show the new Picture?
Just change this line
self.ids.my_picture = 'newPicture.png'
to
self.my_picture = 'newPicture.png'
You are accessing a property not an id.
Related
I have a code, but when it executed it gives a black screen. Tell me what's wrong with it, please.
I try to make a background from a picture on the screen in kivy.
Here is my .py file:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.graphics import Color, Rectangle
from kivy.uix.image import Image
Builder.load_file("Layout.kv")
class SpaceAdventure(App):
def build(self):
return RootManager()
class RootManager(ScreenManager):
pass
class StartScreen(Screen):
pass
if __name__ == '__main__':
SpaceAdventure().run()here
There is my kv file:
<RootScreen>:
transition: FadeTransition()
StartScreen:
<StartScreen>:
name: "start"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'test.jpg'
FloatLayout:
orientation: 'vertical'
MyButton:
text: 'Start'
<MyButton#Button>:
background_color: 1, 1, 1, 1
bold: True
Your MyButton#Button overlayed background.
You add Rectangle to screen with background, then add FloatLayout, then add button with black background. No size hint for button so fill all empty space - actually all your screen.
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()
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
So i have this gridLayout containing only custom buttons that are handled in a specific class. I want that when i click on a button in the gridLayout, another button still in the same gridLayout parent changes it's background_normal property.
It there something like this?
self.parent[otherButtonCol, otherButtonRow].background_normal = 'image.png'
Below is just a simple example for illustration.
Example
main.py
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
class MyWidget(GridLayout):
pass
class TestApp(App):
def build(self):
return MyWidget()
if __name__ == "__main__":
TestApp().run()
test.kv
#:kivy 1.10.0
<MyBigButt#Button>:
text_size: self.size
font_size: "25sp"
markup: True
<MyWidget>:
cols: 1
MyBigButt:
text: "Change Other Button Background Normal Property"
on_release: root.ids.btn2.background_normal = "kivymd_logo.png"
MyBigButt:
id: btn2
Output
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()