Align according to text in GridLayout :kivy - python

iam trying to show the some text right side and some text in left side
here is what i tried :-
from kivy.app import App,runTouchApp
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from io import BytesIO
from PIL import ImageOps, ImageDraw
from PIL import Image as img
from kivy.uix.image import Image, AsyncImage
from kivy.core.image import Image as CoreImage, Texture
from kivy.core.window import Window
from kivy.uix.label import Label
class m(App):
def build(self):
f=FloatLayout()
layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
# Make sure the height is such that there is something to scroll.
layout.bind(minimum_height=layout.setter('height'))
list=[('hhhhbjjggjgjgii',' '),(' ','hgghughuffooeoeo'),(' ','hgghughuffooeoeo'),(' ','hgghughuffooeoeo'),('hhhhbjjggjgjgii\nvhhge\nshh',' '),(' ','hgghughuf\nfooeoeo'),('hhhhbjjggjgjgii',' '),(' ','hgghughuffooeoeo'),('hhhhbjjggjgjgii',' '),(' ','hgghughuffooeoeo'),('hhhhbjj\nggjgjgii',' '),(' ','hgghughuf\nsjsjfooeoeo'),('hhhhbjjg\ngg\nfgg\ngg\ngjgjgii',' '),(' ','hgghughuffooeoeo'),('hhhhbjjggjgjgii',' '),(' ','ab'),('hhhhbjjggjgjgii',' '),(' ','hgghughuffooeoeo')]
for ifu in list:
g=GridLayout(cols=2,rows=1,size_hint_y=None,spacing=200)
if ifu[1]=='ab':
l=Label(text=' ')
g.add_widget(l)
t=Button(background_normal='person-light.png',background_down='person-light.png',size_hint=(1,1))
g.add_widget(t)
else:
if ifu[0]==' ':
l=Label(text=' ')
g.add_widget(l)
ime=Button(text='[color=ffffff]'+ifu[1]+'[/color]',markup=True,size_hint_y=None)
g.add_widget(ime)
else:
ime=Button(text='[color=ffffff]'+ifu[0]+'[/color]',markup=True,size_hint_y=None)
g.add_widget(ime)
l=Label(text=' ')
g.add_widget(l)
layout.add_widget(g)
root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height-100))
root.add_widget(layout)
f.add_widget(root)
return f
m().run()
but it isn't adjusting widtch and hight according to text, i want it to if text is small then width and height of button is also small, and if it is possible make that button rounded at corner's
pls help me out this

You can adjust the size of a Button (or Label) by using its texture_size. You can use:
size_hint: None, None
size: self.texture_size
for a Button or Label, but that make the Button just big enough to hold the text. You can add a few pixels to provide a small space around the text like this in kv:
<MyButt>:
size_hint: None, None
height: self.texture_size[1] + 10
width: self.texture_size[0] + 10
Then in the python code:
class MyButt(Button):
pass
So just load the kv string above and replace usages of Button with MyButt.
You can get rounded buttons by using something like MDFillRoundFlatButton in KivyMD.

by #John Anderson and to adjust the height of GridLayout that of the button i used height: self.minimum_height to avoid overlapping for big buttons

Related

How to position buttons inside a scrollview using kivy

I have some buttons inside a gridlayout in a scrollView that move vertically. I have been trying to postion those buttons at different positions but they are not changing. Please how do I position those buttons at different x and y coordinate. I used floatlayout but it is not working for ScrollView(), why is that?
import kivy
kivy.require('1.8.0')
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
class ScrollViewApp(App):
def build(self):
grid = GridLayout(cols=2, spacing=90, size_hint=(None,None))
grid.bind(minimum_height=grid.setter('height'))
btn1=Button(text='1', size=(90,90), size_hint=(None,None), pos_hint={'center_x':.5, 'center_y': 6})
btn2=Button(text='1', size=(90,90), size_hint=(None,None), pos_hint={'center_x':.5, 'center_y': 2})
btn3=Button(text='1', size=(90,90), size_hint=(None,None), pos_hint={'center_x':.5, 'center_y':.9})
grid.add_widget(btn1)
grid.add_widget(btn2)
grid.add_widget(btn3)
# pos_hint={center_x and center_y} not working
scroll = ScrollView( size_hint=(1, 1), do_scroll_x=False, do_scroll_y=True, scroll_type=['content'])
scroll.effect_cls= 'ScrollEffect'
scroll.add_widget(grid)
return scroll
if __name__ == '__main__':
ScrollViewApp().run()
to do this you can either give the each input of the x and y coordinate yourself:
for i in range(15):
a = float(input(f"Enter X postion value for #00{i}: "))
b = float(input(f"Enter Y postion value for #00{i}: "))
screen.add_widget(Button(text='#00' + str(i), size=(90,90), size_hint=(None,None),pos_hint={'center_x':a, 'center_y':b} ))
or
You can import random and set the different values or use "for" loop to insert different sequential values. I am showing you the examples 'random' below here:
for i in range(15):
a = random.randrange(0,10)
b = random.randrange(1,20)
screen.add_widget(Button(text='#00' + str(i), size=(90,90), size_hint=(None,None),pos_hint={'center_x':a, 'center_y':b} ))
I hope this will help you. And I am not sure about the usage of grid layouts here. You try to remove gridlayouts and just placing these buttons on different coordinate as you have gave the value for spacing of the button in the grid layout which may affect the output display. So, I hope it will work for you. Happy Coding...
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.screenmanager import Screen, ScreenManager
import random
class ScrollViewApp(App):
def build(self):
screen = Screen()
for i in range(3):
a = float(input(f"Enter X postion value for #00{i}: "))
b = float(input(f"Enter Y postion value for #00{i}: "))
screen.add_widget(Button(text='#00' + str(i), size=(90,90), size_hint=(None,None),pos_hint={'center_x':a, 'center_y':b} ))
return screen
if __name__ == '__main__':
ScrollViewApp().run()
This one works fine. I hope this will help you....
float layout should certainly work in scrollview, here's an example:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
import random
class ScrollViewApp(App):
def build(self):
float = FloatLayout(size=(600,1000),size_hint=(None,None))
for i in range(20):
btn1=Button(text=str(i), size=(90,90), size_hint=(None,None), pos_hint={'center_x':random.random(), \
'center_y': random.random()})
float.add_widget(btn1)
scroll = ScrollView( size_hint=(.8, .3), do_scroll_x=False, do_scroll_y=True, scroll_y=0.5,scroll_type=['content','bars'],\
bar_color = [1,0,0,.9],bar_inactive_color=[1,0,0.3,.5],bar_width=25)
scroll.add_widget(float)
return scroll
if __name__ == '__main__':
ScrollViewApp().run()
whereas with the attempted gridlayout, the position of each button will be at regular intervals, at least by default. To get arbitrary offsets at each cell of a gridlayout might be possible, but it would be three times as much work at least as just using float layout.
Note that the size_hint for the float layout is None,None, and the absolute size (600,1000) is intentionally larger than the scrollview (fractional 0.8,0.3 of default Window.size()). Scroll behaviour won't be seen otherwise.

Problem that figures were not drawn in expected cell location on grid layout using canvas

In the following code, there are problems (1) and (2) according to the title.
If kvLang is used as described in this code, the figure (blue ellipse) will be drawn to the expected Cell position (#(1, 1) = upper left).
(However, the character string specified by text: is not displayed at this time. Please tell me how to display text characters .... Problem (1))
I have intended to have coded a Python script to draw with .add_widget method followed to the kvLang.
In this script, the yellow ellipse appears in the lower right instead of the expected Cell position ((2, 2) => lower left) ... problem (2)
For the purpose, it is necessary to add a widget to Grid Laytout using the .add_widget method so that the shape drawn in canvas can be displayed in the cell.
Please tell us how to solve it.
from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Ellipse
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.app import App
Builder.load_string('''
<MyGridLayout#GridLayout>:
cols: 2
Label:
text:"From Kv_1" #(1)Not show. What's problem?
canvas:
Color:
rgb:0,0,1
Ellipse:
pos:self.pos
size:self.size
''')
class MyGridLayout(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.add_widget(Button(text="From_Py_1"))
self.add_widget(Button(text="From_Py_2"))
labl = Button(text="From_Py_canvas_1")
self.add_widget(labl)
with labl.canvas:
# (2) Expected to draw at cell(2,2) which is same locaton as the lable of "From_Py_canvas_1" but not.
Color(rgb=(1, 1, 0))
Ellipse(pos=labl.pos, size_hint=labl.size_hint)
class MyApp(App):
def build(self):
return MyGridLayout()
if __name__ == '__main__':
MyApp().run()
Problem 1: You just need to use canvas.before: instead of canvas: in your kv. This draws the ellipse before the text, instead of after (obscuring the text).
Problem 2: Your Ellipse is the using the current properties of the labl, which are default values until the app is displayed. To fix that, create the Ellipse after by using Clock.schedule_once(). In the modified code below, I saved a reference to labl in order to access it in the draw_yellow_ellipse() method:
from kivy.clock import Clock
from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Ellipse
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.app import App
Builder.load_string('''
<MyGridLayout#GridLayout>:
cols: 2
Label:
text:"From Kv_1" #(1)Not show. What's problem?
canvas.before:
Color:
rgb:0,0,1
Ellipse:
pos:self.pos
size:self.size
''')
class MyGridLayout(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.add_widget(Button(text="From_Py_1"))
self.add_widget(Button(text="From_Py_2"))
self.labl = Button(text="From_Py_canvas_1")
self.add_widget(self.labl)
Clock.schedule_once(self.draw_yellow_ellipse)
def draw_yellow_ellipse(self, dt):
with self.labl.canvas:
# (2) Expected to draw at cell(2,2) which is same locaton as the lable of "From_Py_canvas_1" but not.
Color(rgb=(1, 1, 0))
Ellipse(pos=self.labl.pos, size_hint=self.labl.size_hint)
class MyApp(App):
def build(self):
return MyGridLayout()
if __name__ == '__main__':
MyApp().run()
Also, I don't think the Ellipse honors size_hint. Perhaps you meant to use size=self.labl.size. And if you do that, you will again have an Ellipse obscuring, in this case, your Button.

Kivy scrollable label: impossible to read the beginning and the end of the label

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

Width of root - kivy

I've got a problem with my kivy program... Especially with the width of my root, it's more less than the width of the window...
Like this :
here
I don't understand...
Here my code:
First python file :
from kivy.app import App
from kivy.config import Config
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.button import Button
Config.set('graphics','width','450')
Config.set('graphics','height','800')
class Saisi(Widget):
pass
class Jeu(Widget):
pass
class WorDown(App):
def build(self):
return Jeu()
if __name__ == '__main__':
WorDown().run()
And my kivy file:
<Saisi>:
canvas:
Rectangle:
pos: self.pos
size: root.width , 50 ← I think, this is it...
<Jeu>:
Saisi:
y: root.height / 2
Someone can help me ? I just want to "resize" the "root width", because all my elements have a max width like this...
Thanks for reading.
<Jeu>:
Saisi:
y: root.height / 2
Jeu is a widget and not a special layout type, so it doesn't impose any position or size on its children, therefore the Saisi instance has the default position of (0, 0) and size of (100, 100).
Make Jeu inherit from e.g. BoxLayout (recommended), or alternatively manually set the Saisi pos/size to match that of the Jeu in the above rule.

Change button to image.Load app and display buttons error. KIVY, Python

I'm trying to display an image as an intro to an app. Every time the user runs the program, it should display the image, then when press, it should open a few buttons which are popups.
from kivy.app import runTouchApp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.image import Image
from kivy.lang import Builder
kv = '''
BoxLayoutWithPopup:
orientation:'horizontal'
spacing:10
padding:5
Image:
source: 'appintro.png'
size:100,100
on_press:
root.pop1()
'''
#Helpme:
#title: 'Help Me'
#content: 'helpme.png'
# size_hint: None,None
# pos_hint: 700,320
# size: 250,100
#Games:
# title: 'Games'
# content: 'helpme.png'
# size_hint: None,None
# pos_hint: 100,20
# size: 250,100
class BoxLayoutWithPopup(BoxLayout):
def pop1(self):
# root.add_widget(HelpMe)
# root.add_widget(Games)
helpme = Popup(title='helpme', content=Image(source='helpme.png'),
size_hint=(.8, .8), pos=(1,30), size=(200, 200))
helpme.open()
#def pop2(self):
games = Popup(title='games', content=Image(source='games.png'),
size_hint=(.5, .5), pos=(20,80), size=(200,200))
games.open()
settings = Popup(title='settings', content=Image(source='settings.png'),
size_hint=(.3, .3), pos=(1,1), size=(400, 400))
settings.open()
if __name__ == '__main__':
runTouchApp(Builder.load_string(kv))
Can anyone help me identify what is wrong with this code? I'm trying to display an intro when the app is initialized, which opens the main page when pressed, but the image for the intro and images for the popups are not being displayed. I also tried moving the popup positions, it seem to not be working. please help me.
You are passing a tuple as the pos_hint when it expects a dict. If you want to specify the position, you should use pos instead - so instead of pos_hint=(1,1) you would use pos=(1,1). If you want to specify a position relative to the parent, you can use pos_hint={'x': 0, 'y': 0} for example.

Categories