I am new to kivy. I have chosen a background image and i want to insert a label on it. But it shows like this.
from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
class MyApp(App):
def build(self):
self.box = BoxLayout()
self.img = Image(source = 'image4.png')
self.lbl = Label(text = "Total_Wealth")
self.box.add_widget(self.img)
self.box.add_widget(self.lbl)
return self.box
[![enter image description here][1]][1]MyApp().run()
The BoxLayout automatically stacks the widgets.
If you want to put Label on top of the image, you can use FloatLayout for more control on the placement of the widgets
Related
from kivy.uix.button import Button
from kivy.uix.behaviors.button import ButtonBehavior
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.clock import Clock
from kivy.uix.widget import Widget
from kivy.graphics import BorderImage
from kivy.graphics import Color, RoundedRectangle, Rectangle, Triangle
from kivy.core.window import Window
#from kivy.config import Config
from kivy.uix.checkbox import CheckBox
from kivy.uix.popup import Popup
from kivy.uix.scrollview import ScrollView
from kivy.uix.filechooser import FileChooserListView
from kivy.properties import ObjectProperty
class OpeningPage(FloatLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.but = RoButton(text = 'START', pos = (350,100), font_size=14, size=(100,60), size_hint=(None,None))
self.add_widget(self.but)
class RoButton(Button):
butt = ObjectProperty()
def __init__(self, **kwargs):
super(RoButton, self).__init__(**kwargs)
text = self.text
with self.canvas:
# Color(1., 0, 0)
self.butt = RoundedRectangle( size= self.size, pos = self.pos, radius =[400])
class UI(App):
def build(self):
self.screen_manager = ScreenManager()
self.opening_page = OpeningPage()
screen = Screen(name ='Opening_Page')
screen.add_widget(self.opening_page)
self.screen_manager.add_widget(screen)
return self.screen_manager
if __name__ == '__main__':
the_app = UI()
the_app.run()
Everytime I try to make a circular button using this code I get a box behind the circle. I tried doing self.canvas.before but still no luck if possible could answers be in python rather than .kv language thanks.
Attached image of problem]1
The box you see is the normal Button image. If you don't want that, probably don't use a Button, instead use class RoButton(ButtonBehavior, Widget):.
How to get access to different widgets in python kivy?
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
class kxApp(App):
def build(self):
gl_main = GridLayout(rows=2,padding=5, spacing=5)
gl_left = GridLayout(padding=5, spacing=5)
gl_middle = GridLayout(padding=5, spacing=5)
gl_right = GridLayout(padding=5, spacing=5)
gl_main.add_widget(gl_left)
gl_main.add_widget(gl_middle)
gl_main.add_widget(gl_right)
gl_left.add_widget(TextInput(text='Input Here'))
gl_middle.add_widget(Label(text='Just Label'))
gl_right.add_widget(Button(text='Remove Input Field', on_press killFunc))
def killFunc(self,obj):
#how to get access to TextInput() and remove it?
kxApp().run()
What is the natural way to 'get' widget to manipulate it?
By saving a reference to the TextInput, you can simply use remove_widget:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
class kxApp(App):
def build(self):
gl_main = GridLayout(rows=2,padding=5, spacing=5)
gl_left = GridLayout(cols=1, padding=5, spacing=5)
gl_middle = GridLayout(cols=1, padding=5, spacing=5)
gl_right = GridLayout(cols=1, padding=5, spacing=5)
gl_main.add_widget(gl_left)
gl_main.add_widget(gl_middle)
gl_main.add_widget(gl_right)
self.text_input = TextInput(text='Input Here')
gl_left.add_widget(self.text_input)
gl_middle.add_widget(Label(text='Just Label'))
gl_right.add_widget(Button(text='Remove Input Field', on_press=self.killFunc))
return gl_main
def killFunc(self,obj):
self.text_input.parent.remove_widget(self.text_input)
kxApp().run()
My problem is in accessing container property of DropDown, which is a GridLayout by default and contains it's children.
Simple app:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.label import Label
class TestApp(App):
def build(self):
root = BoxLayout(orientation='vertical')
dropdown = DropDown()
for i in range(3):
dropdown.add_widget(Button(
text=str(i),
size_hint_y=None
)) # add 3 buttons to dropdown
dropdown.container.bind(spacing=8) # this line does not work
dropdown_button = Button(size_hint_y=.2, text='Open DropDown')
dropdown_button.bind(on_release=dropdown.open)
root.add_widget(dropdown_button)
root.add_widget(Label()) # empty space under button
return root
TestApp().run()
I tried using bind method for this, but there is no result. No indentation is set. I also would like to see the solution in kivy language because I want to use dp() function for setting spacing and it's not very convenient to pass the parameter to python file for this. Thanks in advance for any help.
Instead using bind you should just set the value directly:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.widget import Widget
class TestApp(App):
def build(self):
root = BoxLayout(orientation='vertical')
dropdown = DropDown()
for i in range(3):
dropdown.add_widget(Button(
text=str(i),
size_hint_y=None
)) # add 3 buttons to dropdown
dropdown.container.spacing = 10
dropdown.container.padding = (0, 10, 0, 0)
dropdown_button = Button(size_hint_y=.2, text='Open DropDown')
dropdown_button.bind(on_release=dropdown.open)
root.add_widget(dropdown_button)
root.add_widget(Widget()) # empty space under button
return root
TestApp().run()
Using a custom container class is not supported directly. You can do it like this, but its hacky and ugly:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.lang import Builder
Builder.load_string('''
<MyContainer>:
# copied from kivy.uix.dropdown._grid_kv
size_hint_y: None
height: self.minimum_size[1]
cols: 1
# custom settings
spacing: 10
padding: (0, 10, 0, 0)
''')
class MyContainer(GridLayout):
pass
class TestApp(App):
def build(self):
root = BoxLayout(orientation='vertical')
container = MyContainer()
dropdown = DropDown(container=container)
super(DropDown, dropdown).add_widget(container)
dropdown.on_container(dropdown, container)
for i in range(3):
dropdown.add_widget(Button(
text=str(i),
size_hint_y=None
)) # add 3 buttons to dropdown
dropdown_button = Button(size_hint_y=.2, text='Open DropDown')
dropdown_button.bind(on_release=dropdown.open)
root.add_widget(dropdown_button)
root.add_widget(Widget()) # empty space under button
return root
TestApp().run()
So I'd say it'd more clean to make custom spacing class as a subclass of Widget to fill space between buttons:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.lang import Builder
Builder.load_string('''
<DropDownSpacing>:
size_hint_y: None
height: 20
''')
class DropDownSpacing(Widget):
pass
class TestApp(App):
def build(self):
root = BoxLayout(orientation='vertical')
dropdown = DropDown()
for i in range(3):
dropdown.add_widget(DropDownSpacing())
dropdown.add_widget(Button(
text=str(i),
size_hint_y=None
)) # add 3 buttons to dropdown
dropdown_button = Button(size_hint_y=.2, text='Open DropDown')
dropdown_button.bind(on_release=dropdown.open)
root.add_widget(dropdown_button)
root.add_widget(Widget()) # empty space under button
return root
TestApp().run()
This is the same you're doing in your main BoxLayout, except I prefer to use Widget class directly instead of Label with no text.
I have these scrollable labels but I can't read the very beginning and the very end of them(the alphabet starting with 1 and the one starting with 8).
Another issue is that the scrollview starts in the center and jumps back automatically to the center when the scroll is released. It would be better to have it display the left part and let the label where I have stop to scroll.
I use python 3.6 and Kivy 1.9.2.dev0 and my code has to be in python (no .kv file or builder)
import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.label import Label
# from kivy.properties import StringProperty
from kivy.uix.scrollview import ScrollView
class Test(App):
def build(self):
layout_pop = GridLayout (cols=3)
for i in range(3):
l = Label(
text="1abcdefghijklmnopqrstuvwxyz_2abcdefghijklmnopqrstuvwxyz_3abcdefghijklmnopqrstuvwxyz_4abcdefghijklmnopqrstuvwxyz_5abcdefghijklmnopqrstuvwxyz_6abcdefghijklmnopqrstuvwxyz_7abcdefghijklmnopqrstuvwxyz_8abcdefghijklmnopqrstuvwxyz",
font_size=15,
color=(1,1,3,1),
size_hint_x= None,
width=600)
l.bind(size_hint_min_x=l.setter('width'))
scroll = ScrollView(size_hint=(None, None), size=(200, 30))
scroll.add_widget(l)
layout_pop.add_widget(scroll)
return layout_pop
Test().run()
I simply had to use l.bind(texture_size=l.setter('size')). That fixed the 2 issues.
This is the updated def function:
def build(self):
layout_pop = GridLayout (cols=3)
for i in range(3):
l = Label(
text="1abcdefghijklmnopqrstuvwxyz_2abcdefghijklmnopqrstuvwxyz_3abcdefghijklmnopqrstuvwxyz_4abcdefghijklmnopqrstuvwxyz_5abcdefghijklmnopqrstuvwxyz_6abcdefghijklmnopqrstuvwxyz_7abcdefghijklmnopqrstuvwxyz_8abcdefghijklmnopqrstuvwxyz \n1abcdefghijklmnopqrstuvwxyz_2abcdefghijklmnopqrstuvwxyz_3abcdefghijklmnopqrstuvwxyz_4abcdefghijklmnopqrstuvwxyz_5abcdefghijklmnopqrstuvwxyz_6abcdefghijklmnopqrstuvwxyz_7abcdefghijklmnopqrstuvwxyz_8abcdefghijklmnopqrstuvwxyz",
font_size=15,
color=(1,1,3,1),
size_hint_x= None)
l.bind(texture_size=l.setter('size'))
l.bind(size_hint_min_x=l.setter('width'))
scroll = ScrollView(size_hint=(None, None), size=(200, 30))
scroll.add_widget(l)
layout_pop.add_widget(scroll)
return layout_pop
I am trying to adapt the code from the ScrollView doc to have get scrollable labels on the horizontal axis inside a GridLayout. The GridLayout shouldn't be scrollable it, just the labels within it.
For my app, I can't use kv language (either in .kv or the builder), so the code has to be in python.
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.app import runTouchApp
layout = GridLayout(cols=1, spacing=10)
for i in range(10):
label = Label(text="abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz", height = 30, size_hint_x=None, width=400)
label.bind(minimum_width=label.setter('width'))
root = ScrollView(size_hint=(None, 1), size=(label.width, label.height))
root.add_widget(label)
layout.add_widget(root)
runTouchApp(layout)
So far, this is working:
import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
class Test(App):
def build(self):
layout = GridLayout (cols=3)
for i in range(3):
l = Label(font_size=15, size_hint_x= None, width=300, text="This is a very looooooooooooooooooooonnnnnnnnnnnnnnnnnnnng text. Indeed it is a very loooooooooooooooooooooonnnnnnnnnnnnnnnng text")
l.bind(size_hint_min_x=l.setter('width'))
scroll = ScrollView(size_hint=(None, None), size=(100, 400), pos_hint={'center_x':.5, 'center_y':.5})
scroll.add_widget(l)
layout.add_widget(scroll)
return layout
Test().run()