KIVY BoxLayout inside other BoxLayouts - python

So I'm very new to KIVY and I'm trying to make a simple menu sort of thing. The python file is:
from kivy.app import App
class MenuApp(APP):
pass
MenuApp().run()
and the kivy file:
Interface:
<Interface#BoxLayout>:
Label:
text: "logo"
BoxLayout:
orientation: "vertical"
BoxLayout:
Button:
text: "b1"
size_hint: .3, 1
Button:
text: "b2"
Button:
text: "b3"
size_hint: .3, 1
pos_hint: {"center_x": 0.5}
Button:
text: "b4"
size_hint: .3, 1
pos_hint: {"right": 1}
The problem comes from buttons "b1" and "b2". when I give them a size_hint it doesn't change anything. The size_hints on the rest work and these 2 work when i take them out of their BoxLayout. Is this just a thing? that you cant put boxlayers inside 2 other boxlayers? or am I doing something wrong?

from the BoxLayout documentation::
The size_hint uses the available space after subtracting all the
fixed-size widgets.
So the BoxLayout divides the available space according to the size_hint value. In your code the b1 Button has size_hint of .3, while b2 has the default size_hint of 1.0. The sharing algorithm then gives b1 a 0.3/(1.0+0.3) (or 0.230769) share of the available space, and b2 gets 1.0/(1.0+0.3) (or 0.769231) share of the available space. You must consider the size_hints of both of the Buttons, including the default values if you don't assign one.

Related

using scrollview for textinput inside a boxlayout

i am trying to set up a scrollview for textinput in a boxlayout. her is my code in kivy
with the about code i get this
BoxLayout:
size_hint: 1, 4
BoxLayout:
size_hint: .15, 1
ScrollView:
id:scrlv
scroll_type:["content", "bars"]
bar_width: 10
bar_color: 1,0,0
BoxLayout:
size_hint:(1, None)
height:self.minimum_height
#size_hint: 1, 1
TextInput:
#size: 0, "100dp"
height:self.minimum_height
#height: scrlv.height
size_hint:(1, None)
id: notes
color: 1,1,1
BoxLayout:
size_hint: .15, 1
with the above codes, i got the fist picture. although when i start typing, the textinput space extends and once it get to the maximum size, the scroll effect is activated. how do i make the textinput to be in the maximum size from start?

KivyMD Buttons : How increase its dimensions

I am trying to increase the width and the height of a kivyMD button, but it is not supported (size_hint).
•Should I make my own button class that inherits from the Button class ?
•Would that be bad considering I want my app to go on android ?
I would like to know if anyone solved this issue before. Also, if I increase the dimensions of the button, I want the size of the text to change, too...
For example with MDRaised button type
This is how you do it:
MDRaisedButton:
text: "Do Something"
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: app.do_anything()
size: 30, 30
size_hint: None, None
Make sure you set size_hint to None, None and then specify size: width, height
This is an old post but I ran into the same issue.
I had to use it a percentage of the root width and it worked.
Example below:
MDRectangleFlatButton:
text: "Some text"
pos_hint: {"center_x": .5}
size_hint: None, None
width: root.width*0.4

Multiple classes in one screen stops FloatLayout from working correctly

I am trying to incorporate ads into a Kivy app I made, and to do this, I want to have one class (with the ads) in a FloatLayout to be at the top of my screen, and the rest of the app to be below, in a separate class.
I was trying to get this to work with some test code (simple .py and .kv file that has multiple screens and classes and organizes accordingly). The code is supposed to have two float layouts: One has text, the other has a button that you press and it takes you to the next screen. However the issue I am having is that I can't position the button correctly, as it appears that the widget is shrunk in the bottom left corner. It is supposed to be next to the text box.
Here is my .kv file:
WindowManager:
Screen1:
Screen2:
<Screen1>:
name: "screen1"
FloatLayout:
Label:
pos_hint: {'top': 1, "center_x": 0.5}
size_hint: (0.2, 0.5)
font_size: 40
text: "TEXT AT TOP OF SCREEN"
FloatLayout:
TextInput:
pos_hint: {"x": 0.1, "y": 0.05}
size_hint: (0.3, 0.05)
multline:False
GoS:
FloatLayout:
Button:
text: "PRESS TO GO TO SCREEN 2"
pos_hint: {"right": 0.5, "center_y": 0.7}
on_press: widget.goscreen()
<Screen2>:
name: "screen2"
Label:
text: "YOU ARE ON SCREEN TWO"
and here is the .py file:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
class Screen1(Screen):
pass
class GoS(Widget):
def goscreen(self):
self.parent.current = "screen2"
class Screen2(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file("rec_view.kv")
class TestApp(App):
def build(self):
return kv
if __name__ == "__main__":
TestApp().run()
Why is this happening?
Another small point also is that my button doesn't work because I can't seem to call the correct class. If I use "root.goscreen()", it doesn't work as my root widget doesn't have this function. What should be the correct syntax here?
I recommend you to use BoxLayout to divide your GUI.
Your button don't work because you don't link it to a valid Widget.
The GoS widget must be define in KV or be imported.
Here is a proposition for your rec_view.kv file :
WindowManager:
Screen1:
Screen2:
<GoS>:
Button:
text: "PRESS TO GO TO SCREEN 2"
on_press: root.goscreen()
<Screen1>:
name: "screen1"
BoxLayout:
orientation: "vertical"
BoxLayout:
orientation: "horizontal"
size_hint_y: 0.5 # Proportion of screen height that the widget occupe
Label:
font_size: 40
text: "TEXT AT TOP OF SCREEN"
BoxLayout:
orientation: "horizontal"
size_hint_y: 0.3
TextInput:
multline:False
BoxLayout:
orientation: "horizontal"
size_hint_y: 0.2
GoS:
<Screen2>:
name: "screen2"
Label:
text: "YOU ARE ON SCREEN TWO"
The definition of goscreen is not correct, GoS is not a Screen, so his parent don't have current , use instead App.get_running_app().root.current = "screen2".
I don't know what you want to do and why you define the GoS class, but you can avoid it. By moving the goscreen definition into Screen1 class, and replace the 3rd BoxLayout of Screen1 with this:
BoxLayout:
orientation: "horizontal"
size_hint_y: 0.2
Button:
text: "PRESS TO GO TO SCREEN 2"
on_press: root.goscreen()

Can I automatically press a button on hitting 'return'-key in a textinput?

I'm currently working on an application with Kivy.
On one screen I have a TextInput and a button. I can input text and go to the next screen by pressing the button.
My question is: Is there a way to just hitting the 'return'-key after typing in your text and automatically press the button without actually touching it?
And a small question on the side: I put
focus: True
under TextInput so it would focus the textinput immediately when I go to the screen. But it won't work. After some google searching a lot of people said it was a bug, although those comments are fairly old (< 1 year). Is this still bugged or is there a solution to this?
TextInput:
focus: True
pos_hint: {'x': .3, 'top': .8}
size_hint: .4, .05
id: search
multiline:False
Button:
text: 'back'
font_size: 25
size_hint: .3, .15
pos_hint: {'x':.15, 'top': .4}
on_release:
app.root.current = 'main'
root.manager.transition.direction = 'right'
You should use this in your TextInput:
on_text_validate:
app.root.current = 'main'
root.manager.transition.direction = 'right'
For the auto focus thingy, I use sub-classing.
In the .py I create a new class for TextInput and use this instead..
class MyTextInput(TextInput):
""" TextInput with auto-focus
"""
def __init__(self, **kwargs):
super(MyTextInput, self).__init__(**kwargs)
def set_focus(dt):
self.focus = True
Clock.schedule_once(set_focus, .1)

How do I pass variables through different classes or root widgets in kivy?

I'm creating an app where I determine a variable in one class and need to transfer it to a different class. I wanted to use id but that doesn't work for different root widgets. Then I found out about factory and it seemed promising and it seems to work somewhat but when I update the variable in the PopupColor class it doesn't update in my DrawScreen class.
Here's the code.
py:
class PopupColor(Popup):
color = [0,0,0,1]
def on_press_dismiss(self, colorpicker, *args):
print(self.color)
self.dismiss()
self.color = colorpicker.color
print(self.color)
class DrawScreen(Screen):
def testy(self):
self.color = Factory.PopupColor().color
print(self.color)
kv:
<PopupColor>:
title: 'Pick a Color'
size_hint: 0.75, 0.75
id: popupcolor
BoxLayout:
padding: 5
spacing: 5
orientation: 'vertical'
ColorPicker:
id: colorpicker
size_hint: 1.0, 1.0
Button:
text: 'Choose Color'
size_hint: 1, 0.2
on_release: popupcolor.on_press_dismiss(colorpicker)
<DrawScreen>:
Button:
size_hint: 0.2,0.1
font_size: 30
text: "Back"
on_release: Factory.PopupColor().open()
ColorButton:
text: "Test"
pos_hint:{"center_x":0.5, "y":0.1}
on_release: root.testy()
So how can I do this and how far off am I?
EDIT: So it seems like the error isn't really the factory part but more so that the variable in PopupColor doesn't change permanently.
The problem is that when you change the attribute, you use self, which refers to this instance.
But since you create a new PopupColor object, each time you open the popup, you need to treat color as a shared variable.
So you could change color like this:
PopupColor.color = colorpicker.color
That way you treat the attribute color as shared with all PopupColor objects.

Categories