I have drawn a circle. I want to place a button at the same position of the circle. How can I get the circle's x and y coordinates. My code(in kv file):
MainWidget:
<MainWidget>:
canvas.after:
Color:
rgb: 1, 0, 0
Ellipse:
id: point
size: 100, 100
pos: 100, root.y1
Button:
id: No1
pos: point.pos
on_press: root.move()
It shows "NameError: name 'point' is not defined"
Put your widgets in BoxLayout. You can't use id for canvas, you should use groups.
Circle above the button.
from kivy.lang import Builder
from kivy.app import App
KV = '''
Screen:
BoxLayout:
orientation: 'vertical'
spacing: 10
BoxLayout:
size_hint_x: None
pos_hint: {'center_x': .5}
canvas.after:
Color:
rgb: 1, 0, 0
Ellipse:
size: 100, 100
pos: self.pos
BoxLayout:
Button:
id: No1
on_press: pass
'''
class Test(App):
def build(self):
return Builder.load_string(KV)
Test().run()
Circle in the button.
from kivy.lang import Builder
from kivy.app import App
KV = '''
Screen:
BoxLayout:
padding: 50
Button:
on_press: pass
canvas.after:
Color:
rgb: 1, 0, 0
Ellipse:
size: self.size
pos: self.pos
'''
class Test(App):
def build(self):
return Builder.load_string(KV)
Test().run()
So you can place the circle at the same position as the button.
Ellipse:
size: 100, 100
pos: self.pos
Related
I am making an app where I will have many different labels for dropdown lists. These dropdown lists will be activated by a button that will show the dropdown.
My problem is that I do not know how to have multiple dropdowns using only one class in my python code. Currently, I have to make multiple classes and multiple methods to activate different dropdown menus and to have those dropdown menus come from different classes.
Trying to modify the show_dropDown() didn't work since i couldn't get the labels to show and the button to link the dropdown menu from.
main.py
from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.dropdown import DropDown
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import Screen
Window.size = (286.110236, 570.33070866)
class HomeScreen(Screen):
pass
class CustomDropDown(DropDown):
pass
class CustomDropDown2(DropDown):
pass
class ButtonGrid(ButtonBehavior, GridLayout):
def show_dropDown(self):
dropdown = CustomDropDown()
dropdown.open(self)
def show_dropDown2(self):
dropdown = CustomDropDown2()
dropdown.open(self)
GUI = Builder.load_file("main.kv")
class MainApp(App):
def build(self):
return GUI
MainApp().run()
kv-file:
#:import utils kivy.utils
#:import Factory kivy.factory.Factory
<ButtonGrid>:
<CustomDropdown>:
id: dropdown
Label:
id: label1
text: 'Dropdown 1'
size_hint_y: None
height: 400
background_color: (0, 1, 0, .9)
canvas.before:
Color:
rgba: self.background_color
Rectangle:
size: self.size
pos: self.pos
<CustomDropdown2>:
id: dropdown2
Label:
id: label2
text: 'Dropdown 2'
size_hint_y: None
height: 400
background_color: (1, 0, 1, .9)
canvas.before:
Color:
rgba: self.background_color
Rectangle:
size: self.size
pos: self.pos
<HomeScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#FFFFFF")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 8
cols: 1
spacing: 10
size_hint_y: None
height: 1200
width: self.minimum_width
ButtonGrid:
id: button1
cols:1
rows:1
size_hint: 1, None
height: 185.71
on_press:
self.show_dropDown()
background_color: (1,0,0,1)
canvas.before:
Color:
rgba: self.background_color
Rectangle:
size: self.size
pos: self.pos
Label:
text: "Button 1"
ButtonGrid:
id: button2
cols:1
rows:1
size_hint: 1, None
height: 185.71
on_press:
self.show_dropDown2()
background_color: (0,0,1,1)
canvas.before:
Color:
rgba: self.background_color
Rectangle:
size: self.size
pos: self.pos
Label:
text: "Button 2"
You can add property (or properties) to your CustomDropDown class (or may be to ButtonGrid) and link it to associated widget as follows:
First in .py
class CustomDropDown(DropDown):
text = StringProperty("")
Then in .kv
<CustomDropdown>:
id: dropdown
Label:
id: label1
text: root.text
size_hint_y: None
...
Now call them as you need with some added args/kwargs,
...
GridLayout:
rows: 8
cols: 1
spacing: 10
size_hint_y: None
height: 1200
width: self.minimum_width
ButtonGrid:
id: button1
cols:1
rows:1
size_hint: 1, None
height: 185.71
on_press:
self.show_dropDown('Dropdown 1')
background_color: (1,0,0,1)
canvas.before:
Color:
rgba: self.background_color
Rectangle:
size: self.size
pos: self.pos
Label:
text: "Button 1"
ButtonGrid:
id: button2
cols:1
rows:1
size_hint: 1, None
height: 185.71
on_press:
self.show_dropDown(value='Dropdown 2')
background_color: (0,0,1,1)
And handle those calls in one go,
class ButtonGrid(ButtonBehavior, GridLayout):
def show_dropDown(self, value = ""):
dropdown = CustomDropDown(text = value)
dropdown.open(self)
I am a beginner in Language and I am trying to make a simple guessing game and I would like to know how I use the data entered in the Players Class in the Start_p1 Class. I want the name typed in the TextInput of the Players Class, to appear in the Label Text: of the Start_p1 Class.
Arquivo .py:
import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.textinput import TextInput
from kivy.properties import StringProperty
class Home(Screen):
def next(self):
self.manager.current = "players"
class Players(Screen):
def start(self):
self.manager.current = 'st1'
class Start_p1(Screen):
def runn(self):
self.manager.current = 'st2'
class Start_p2(Screen):
def back(self):
self.manager.current = 'st1'
class Finish(Screen): pass
class Myapp(App):
sm = None
def build(self):
self.sm = ScreenManager()
self.sm.add_widget(Home(name = 'home'))
self.sm.add_widget(Players(name = 'players'))
self.sm.add_widget(Start_p1(name = 'st1'))
self.sm.add_widget(Start_p2(name = 'st2'))
self.sm.add_widget(Finish(name = 'finish'))
self.sm.current = 'home'
return self.sm
if __name__ == '__main__':
Myapp().run()
Arquivo.kv
#: import utils kivy.utils
<Home>:
FloatLayout:
canvas.before:
Color:
rgb: utils.get_color_from_hex('#2169af')
Rectangle:
pos: self.pos
size: self.size
Button:
text: 'Iniciar'
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint: 0.2, .1
background_color: utils.get_color_from_hex('#13447d')
on_release: root.next()
Button:
text: 'Configurações'
pos_hint: {'center_x': .5, 'center_y': .4}
size_hint: 0.2, .1
background_color: utils.get_color_from_hex('#13447d')
<Players>:
FloatLayout:
canvas.before:
Color:
rgb: utils.get_color_from_hex('#2169af')
Rectangle:
pos: self.pos
size: self.size
Label:
pos: 0, 270
text: 'JOGADORES'
Label:
pos: 0, 150
text: 'Informe o nome do 1° Jogador:'
TextInput:
id: txtt
pos: 270, 400
size: 250, 30
multiline: False
Label:
pos: 0, -20
text: 'Informe o nome do 2° Jogador:'
TextInput:
id: txt
pos: 270, 230
size: 250, 30
multiline: False
Button:
text: 'Iniciar'
pos_hint: {'center_x': .5, 'center_y': .2}
size_hint: 0.2, .1
background_color: utils.get_color_from_hex('#13447d')
on_release: root.start()
<Start_p1>:
Players:
id: players
FloatLayout:
canvas.before:
Color:
rgb: utils.get_color_from_hex('#2169af')
Rectangle:
pos: self.pos
size: self.size
Label:
text:
That is actually a bit tricky. One would expect that you can use:
Label:
text: app.sm.get_screen('players').ids.txt.text
That will technically work, but it won't set up the automatic update if the text of the TextInput changes. A careful reading the documentation explains why, and suggests a work around. Using the suggestion from the documentation, you can do something like this:
Label:
players_screen: app.sm.get_screen('players')
text: self.players_screen.ids.txt.text
This produces the desired result with automatic updates.
App icon
I have designed a sample code in which I am using my app icon but it looks very tiny. Right now my icon size is 100 x 36. When I run the program, icon looks really very tiny. I am trying to increase the size of it so it should be visible to us.
Border Box around the Text
And also I need to border the text only with box but the border is created to whole label area.
Problems
Is it possible to increase the size of icon?
I need only to box the label text.
My sample code:
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.lang import Builder
Builder.load_string('''
<MainScreen>:
GridLayout:
orientation: 'vertical'
cols: 1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
GridLayout:
padding: [10, 10, 10, 10]
spacing: [10,10]
orientation: 'vertical'
cols: 1
size_hint: 1, .1
canvas:
Color:
rgba: .1, .1, 1, .9
Line:
width: 1.
rectangle: (self.x, self.y, self.width, self.height)
Label:
text: 'INPUTS'
color: 0,0,0,1
GridLayout:
padding: [10, 10, 10, 10]
spacing: [10,10]
orientation: 'vertical'
cols: 1
size_hint: 1, .1
canvas:
Color:
rgba: .1, .1, 1, .9
Line:
width: 1.
rectangle: (self.x, self.y, self.width, self.height)
Label:
text: 'OUTPUTS'
color: 0,0,0,1
''')
class MainScreen(FloatLayout):
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
class TestApp(App):
def build(self):
self.icon = 'fif.png'
self.title = 'sample_v_1.1'
return MainScreen()
if __name__ == "__main__":
TestApp().run()
App Icon Size
I don't think that you can change the icon's size for your application.
Application » icon
icon
Icon of your application. The icon can be located in the same
directory as your main file.
Recommended 256x256 or 1024x1024? for GNU/Linux and Mac OSX 32x32 for
Windows7 or less. <= 256x256 for windows 8 256x256 does work (on
Windows 8 at least), but is scaled down and doesn’t look as good as a
32x32 icon.
Box Border around Text
To draw a box surrounding the text use the following:
Snippet - kv file
Label:
canvas:
Color:
rgba: .1, .1, 1, .9
Line:
width: 1.
rectangle: (int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.), self.texture_size[0], self.texture_size[1])
Example
main.py
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
Builder.load_string('''
<MainScreen>:
inputs: inputs
outputs: outputs
GridLayout:
orientation: 'vertical'
cols: 1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
GridLayout:
padding: [10, 10, 10, 10]
spacing: [10,10]
orientation: 'vertical'
cols: 1
size_hint: 1, .1
Label:
canvas:
Color:
rgba: .1, .1, 1, .9
Line:
width: 1.
rectangle: (int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.), self.texture_size[0], self.texture_size[1])
id: inputs
text: 'INPUTS'
color: 0,0,0,1
GridLayout:
padding: [10, 10, 10, 10]
spacing: [10,10]
orientation: 'vertical'
cols: 1
size_hint: 1, .1
Label:
canvas:
Color:
rgba: .1, .1, 1, .9
Line:
width: 1.
rectangle: (int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.), self.texture_size[0], self.texture_size[1])
id: outputs
text: 'OUTPUTS'
color: 0,0,0,1
''')
class MainScreen(FloatLayout):
pass
class TestApp(App):
icon = 'ac013.png'
title = 'sample_v_1.1'
def build(self):
return MainScreen()
if __name__ == "__main__":
TestApp().run()
Output
t3.py
#-*- coding: utf-8 -*-
__version__ = "1.0"
import kivy
import os
kivy.require('1.10.0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.core.window import Window
Window.size = (540, 960)
class StationTest(Screen):
def __init__(self, **kwargs):
super(StationTest, self).__init__(**kwargs)
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file("t3.kv")
class Test2App(App):
def build(self):
return presentation
Test2App().run()
t3.kv
# -*- coding: utf-8 -*-
#:kivy 1.10.0
#:import NoTransition kivy.uix.screenmanager.NoTransition
#:import SlideTransition kivy.uix.screenmanager.SlideTransition
#:import Button kivy.uix.button.Button
ScreenManagement:
transition: SlideTransition(direction='left')
StationTest:
<StationTest>:
name: 'StationTest'
canvas:
Rectangle:
pos: self.pos
size: self.size
source: 'image/background.png' #backgroundimage
header: _header
ScrollView:
FloatLayout:
size_hint_y: None
height: 500
BoxLayout:
id: _header
orientation: 'vertical'
size_hint: 1, 0.10
pos_hint: {'top': 1.0}
anchor: _anchor
canvas:
Color:
rgba: 0.8, 0.6, 0.4, 1.0
Rectangle:
pos: self.pos
size: self.size
Label:
text: "STATION > STATION"
font_size: 40
BoxLayout
id: _anchor
size_hint_y: 0.3
canvas.before:
Color:
rgba: 0.3, 0.5, 0.8, 1.0
Rectangle:
pos: self.pos
size: self.size
Label:
text: "TEST1234"
BoxLayout:
orientation: 'vertical'
#size_hint: 1, 0.35
size: 1,0.35
spacing: 10
pos_hint:{"center_x":0.5,"y":-0.6}
padding: 0, -200, 0, 0
GridLayout:
cols: 1
rows: 10
spacing: 0
padding: [0,100]
on_parent:
for i in range(10): txt = 'abcdef'; self.add_widget(Button(text = txt, text_size=(cm(2), cm(2)), background_color=(255,255,255,1),
pos=self.pos, id=txt, color=(0,0,0,1))) # 0~1.0
i want add '123456' text apart from 'abcdef' in one button. i can code txt = 'abcdef' + '123456' but this is not i wanted. I would like to add the texts in the button and apply the desired options to each text, but it is not easy.
on_parent:
for i in range(10): txt = 'abcdef'; self.add_widget(Button(text = txt, text_size=(cm(2), cm(2)), background_color=(255,255,255,1),
pos=self.pos, id=txt, color=(0,0,0,1))) # 0~1.0
So I have two questions.
1.Can I put two texts that can move independently in one button?
2.Is it possible to set the position of the text freely within the button?
Can I put two texts that can move independently in one button? No, you cannot
Is it possible to set the position of the text freely within the button? No, you cannot
Solution
Create custom button with inheritance of ButtonBehavior and BoxLayout. Inside the BoxLayout, there are three Label widgets.
Snippet
<CustomLabel#Label>:
text_size: root.width, None
size: self.texture_size
valign: 'center'
halign: 'right'
<CustomButton>:
color: 0, 0, 0, 1 # black color text
orientation: 'vertical'
canvas.before:
Rectangle:
size: self.size
pos: self.pos
size_hint: 1, None
height: 60
padding: 5, 5, 5, 5
background_color: [0.50196, 0.50196, 0.50196, 1] if self.state == 'normal' else [0, 1, 1, 1]
AnchorLayout:
canvas.before:
Color:
rgba: [1, 1, 1, 1] if root.background_color is None else root.background_color
Rectangle:
size: self.size
pos: self.pos
AnchorLayout:
anchor_x: 'left'
anchor_y: 'top'
CustomLabel:
text: root.route
color: root.color
halign: 'left'
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
CustomLabel:
text: root.stations
color: root.color
AnchorLayout:
canvas.before:
Color:
rgba: [1, 1, 1, 1] if root.background_color is None else root.background_color
Rectangle:
size: self.size
pos: self.pos
anchor_x: 'right'
anchor_y: 'bottom'
CustomLabel:
text: root.commute
color: root.color
Example
main.py
#-*- coding: utf-8 -*-
__version__ = "1.0"
import os
import kivy
kivy.require('1.11.0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
Window.size = (540, 960)
from kivy.uix.button import ButtonBehavior
from kivy.properties import StringProperty
def oopath(ndid, uor):
path = os.path.join(os.path.dirname(__file__), ndid + '.txt')
return path
##############################################################################################################
class StationTest(Screen):
def __init__(self, **kwargs):
super(StationTest, self).__init__(**kwargs)
oo = oopath('TESTTEST', 0)
self.rpandgv(oo)
def rpandgv(self, path):
with open(path) as businfo:
Businfo = []
for line in businfo:
Businfo.append(line.rstrip())
self.businfolist = Businfo
self.lenbil = int(len(Businfo))
self.numberoflist = int(len(Businfo)/3)
def populate_businfo(self, instance):
for x in range(0, self.lenbil, 3):
instance.add_widget(CustomButton(route=self.businfolist[x], stations=self.businfolist[x+1], commute=self.businfolist[x+2]))
class ScreenManagement(ScreenManager):
pass
class CustomButton(ButtonBehavior, BoxLayout):
route = StringProperty('')
stations = StringProperty('')
commute = StringProperty('')
def on_release(self):
print("\troute={0}, stations={1}, commute={2}".format(self.route, self.stations, self.commute))
presentation = Builder.load_file("test.kv")
class Test2App(App):
def build(self):
return presentation
Test2App().run()
test.kv
# -*- coding: utf-8 -*-
#:kivy 1.11.0
#:import NoTransition kivy.uix.screenmanager.NoTransition
#:import SlideTransition kivy.uix.screenmanager.SlideTransition
#:import Button kivy.uix.button.Button
ScreenManagement:
transition: SlideTransition(direction='left')
StationTest:
<StationTest>:
name: 'StationTest'
canvas:
Rectangle:
pos: self.pos
size: self.size
source: 'image/background.png' #backgroundimage
header: _header
ScrollView:
FloatLayout:
size_hint_y: None
height: 500
BoxLayout:
id: _header
orientation: 'vertical'
size_hint: 1, 0.10
pos_hint: {'top': 1.0}
anchor: _anchor
canvas:
Color:
rgba: 0.8, 0.6, 0.4, 1.0
Rectangle:
pos: self.pos
size: self.size
Label:
text: "STATION > STATION"
font_size: 40
BoxLayout
id: _anchor
size_hint_y: 0.3
canvas.before:
Color:
rgba: 0.3, 0.5, 0.8, 1.0
Rectangle:
pos: self.pos
size: self.size
Label:
text: "TEST1234"
BoxLayout:
orientation: 'vertical'
#size_hint: 1, 0.35
size: 1,0.35
spacing: 10
pos_hint:{"center_x":0.5,"y":-0.6}
padding: 0, -200, 0, 0
GridLayout:
cols: 1
rows: 10
spacing: 0
padding: [0,100]
on_parent:
root.populate_businfo(self)
<CustomLabel#Label>:
text_size: root.width, None
size: self.texture_size
valign: 'center'
halign: 'right'
<CustomButton>:
color: 0, 0, 0, 1 # black color text
orientation: 'vertical'
canvas.before:
Rectangle:
size: self.size
pos: self.pos
size_hint: 1, None
height: 60
padding: 5, 5, 5, 5
background_color: [0.50196, 0.50196, 0.50196, 1] if self.state == 'normal' else [0, 1, 1, 1]
AnchorLayout:
canvas.before:
Color:
rgba: [1, 1, 1, 1] if root.background_color is None else root.background_color
Rectangle:
size: self.size
pos: self.pos
AnchorLayout:
anchor_x: 'left'
anchor_y: 'top'
CustomLabel:
text: root.route
color: root.color
halign: 'left'
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
CustomLabel:
text: root.stations
color: root.color
AnchorLayout:
canvas.before:
Color:
rgba: [1, 1, 1, 1] if root.background_color is None else root.background_color
Rectangle:
size: self.size
pos: self.pos
anchor_x: 'right'
anchor_y: 'bottom'
CustomLabel:
text: root.commute
color: root.color
Output
I am trying to center a circle inside a layout. I'm currently doing some padding calculations, but I'm also looking for a better way. I imagine one of the predefined layouts may be a better choice. Here's what my code is producing...
For square layouts:
For wide layouts:
This is the right behavior, which is great, but is there a better way? I can imagine this getting messy with non-circle shapes, for example.
Here's my code:
#!/usr/bin/kivy
import kivy
kivy.require('1.7.2')
from random import random
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Color, Ellipse, Rectangle
class MinimalApp(App):
title = 'My App'
def build(self):
root = RootLayout()
return(root)
class RootLayout(AnchorLayout):
pass
class Circley(RelativeLayout):
pass
if __name__ == '__main__':
MinimalApp().run()
And the KV:
#:kivy 1.7.2
#:import kivy kivy
<RootLayout>:
anchor_x: 'center' # I think this /is/ centered
anchor_y: 'center'
canvas.before:
Color:
rgba: 0.4, 0.4, 0.4, 1
Rectangle:
pos: self.pos
size: self.size
Circley:
anchor_x: 'center' # this is /not/ centered.
anchor_y: 'center'
canvas.before:
Color:
rgba: 0.94, 0.94, 0.94, 1
Ellipse:
size: min(self.size), min(self.size)
pos: 0.5*self.size[0] - 0.5*min(self.size), 0.5*self.size[1] - 0.5*min(self.size)
Label:
text: unicode(self.size) # this is /not/ appearing
color: 1,0,0,1
Snippet using FloatLayout, size_hint and pos_hint:
from kivy.app import App
from kivy.lang import Builder
kv = '''
FloatLayout:
Widget:
size: min(root.size), min(root.size)
size_hint: None, None
pos_hint: {'center_x': .5, 'center_y': .5}
canvas:
Color:
rgb: 1, 0, 0
Ellipse:
size: self.size
pos: self.pos
'''
Builder.load_string(kv)
class MyApp(App):
def build(self):
return Builder.load_string(kv)
MyApp().run()
Flag of Japan:
from kivy.app import App
from kivy.lang import Builder
kv = '''
FloatLayout:
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
size: self.size
pos: self.pos
Widget:
size: min(root.size)/2, min(root.size)/2
size_hint: None, None
pos_hint: {'center_x': .5, 'center_y': .5}
canvas:
Color:
rgb: 1, 0, 0
Ellipse:
size: self.size
pos: self.pos
'''
Builder.load_string(kv)
class MyApp(App):
def build(self):
return Builder.load_string(kv)
MyApp().run()