I have tried to add a simple scroll view on PC, I define the scroll view like any other widget and then adds its layout and that I then add the widgets.
Here is the code I use:
Window.size = (339, 600)
self.w1 = self
with self.w1.canvas.before:
Color(0.941176, 0.941176, 0.941176, 1)
self.rect = Rectangle(size=self.w1.size, pos=self.w1.pos)
self.w1.bind(pos=self.update_rect, size=self.update_rect)
self.scroll1 = ScrollView(size_hint=(None, 1), size=(Window.width, Window.height),scroll_type = ['bars',"content"])
self.w1.add_widget(self.scroll1)
self.scroll1_layout = RelativeLayout(pos_hint ={'x':0.0, 'y':0.0},size_hint = (0.626844, 1))
self.scroll1.add_widget(self.scroll1_layout)
self.button1 = Button(text = "Button", pos_hint ={'x':0.568182, 'y':0.47585}, size_hint = (1.30682, 0.0545617))
self.scroll1_layout.add_widget(self.button1)
self.button2 = Button(text = "Button", pos_hint ={'x':0.227273, 'y':0.864937}, size_hint = (0.909091, 0.0992844))
self.scroll1_layout.add_widget(self.button2)
How do I make it so that it has a button and below the widget origin. the widget origin is the bottom left of the widget and the bottom below it would not be visible until I scrolled down.
Thank You for any help.
Related
I try to change the size_hint of a button in Python, Kivy, but every value i put there the size of the button remain the same.. for the pos is changing but for the size_hint no, and if i change from pos to pos_hint the button is stuck in the corner of the window and from there i cant change nothing... also i tried to stick the pos of the button on a position where is a text in the photo but every time when i resize the kivy window the button and image are changing theyr position.. how i can solve this probelm ?? THANKSSS !!
from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.button import Button
from random import choice
class MyImage(Image):
images = ["Q1.png", "Q2.png", "Q3.png"] # ........
def __init__(self, **kwargs):
super().__init__(**kwargs)
correct = Button(pos=(200, 200), size_hint=(.1, .1), on_release=self.random_image, background_color=(1, 1, 1, 0.2))
self.add_widget(correct)
self.random_image()
def random_image(self, *_):
self.source = choice(self.images)
class RandomQuestionApp(App):
def build(self):
return MyImage()
randomApp = RandomQuestionApp()
RandomQuestionApp().run()
Try size instead of size_hint.
correct = Button(
pos=(200, 200),
size=(100, 100),
on_release=self.random_image,
background_color=(1, 1, 1, 0.2)
)
size : This is for static sizing of widgets and takes two arguments
i.e. (width, height). Default size of the button = (100, 100).
size_hint : This is for dynamic sizing of the button and provide hint
of size. It contains two arguments i.e. width and height it can be
floating values.By default, all widgets have their size_hint=(1, 1).
If there is nothing that influences the button size, your dynamics won't do anything. Size on the other hand would define a fixed size of the button where 100x100 is the default.
I have three buttons (one column, three rows) in a GridLayout.
The text on the top of the button is centered but when it is too long it extends past the screen. How do I wrap it? Current code is:
self.add_widget(Button(text="", text_size = (None, self.height), halign = "center", valign = "center"))
for each of the buttons.
Setting
text_size = (None, self.height)
as an arg to the Button constructor does not set up a binding. It just sets the text_size to the values at the moment that the Button __init__() method is executed. So the text_size gets set to (None, 100) and stays that way (the default height of a widget is 100). If you want to actually have such a binding, you must either use the Kivy language, or set up the binding yourself. Something like this:
butt = Button(text="", text_size = self.size, halign = "center", valign = "center")
butt.bind(size=self.resize)
self.add_widget(butt)
def resize(self, butt, new_size):
butt.text_size = new_size
def build(self):
layout=FloatLayout()
# use a (r, g, b, a) tuple
btn1 = Button(text ="Push Me !",
background_color =(1, 1, 1,1)
size =(32, 32),
size_hint =(.2, .2),
pos =(300, 250))
btn2 = Button(text ="click Me !",
background_color =(1, 0, 1,1)
size =(32, 32),
size_hint =(.2, .2),
pos =(100, 250))
layout.add_widget(btn1)
layout.add_widget(btn2)
# I need a function here to print a text only if the two buttons are clicked one after another.
return layout
You can for example update a varibale value when the first button is clicked. Then, when the second button is clicked you check the value of this variable if it has the right value you print the text, and of course, you reset the variable.
Here is a simple code:
var_click = 0
def click1(*events):
global var_click
var_click = 1
def click2(*events):
global var_click
if var_click == 1:
var_click = 0
print("Some text")
Then you have just to associate these two functions to command parameter of btn1 and btn2 respectively.
For some reason my kivy dropdown list is not showing and im following the exact method from the documentation. Still no avail. ill appreciate any help. Here is my code.
class NewProjectScreen(Screen):
def __init__(self, **kwargs):
super(NewProjectScreen, self).__init__(**kwargs)
self.location = TextInput(multiline = True, pos_hint = {"center_x": 0.5, "center_y": 0.6}, hint_text = "Location", size_hint = [0.4, 0.10], font_name = 'fonts/Qanelas-Light.otf', id = "location")
self.add_widget(self.location)
self.location.bind(text = self.dropdown)
def dropdown(self, instance, value):
if len(self.location.text) > 0:
towns_cities = 'https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=' + self.location.text + "&inputtype=textquery&fields&types=geocode&sensor=false&types=regions&key=" + API_KEY
response = urllib.request.urlopen(towns_cities).read()
directions = json.loads(response)
print(directions)
for places in directions:
place = places
self.dropdown = DropDown()
for index in range (5):
btn = Button(text = places[index])
self.dropdown.add_widget(btn)
btn.bind(on_release=lambda btn: self.dropdown.select(btn.text))
self.dropdown.open(btn)
Several problems with your code.
Your code self.dropdown = DropDown() redefines self.dropdown, which is a method of your NewProjectScreen class. I suggest refactoring to change the name of that method.
Your code self.dropdown.open(btn) tries to attach the DropDown to one of its own buttons (probably won't work). I suggest replacing that with self.dropdown.open(self.location).
As mentioned in the documentation "When adding widgets, we need to specify the height manually". I suggest modifying your Button creation to btn = Button(text = places[index], size_hint=(1, None), height=50).
I believe the above changes will get your code working.
I'm trying to make a custom layout using kivy, I need to generate a gridlayout with scrollview buttons and put it inside of another layout.
Everytime I click the button that generates the buttons it pushes the "get links" button up and if I click it a second time instead of adding buttons to the existing gridlayout it creates a new gridlayout.
This is the app before I press the 'get links' button
The first time I press the 'get links' button
The second time the button is pressed
class RootWidget(BoxLayout):
pass
class Scrollbox(BoxLayout):
def __init__(self, **kwargs):
super(Scrollbox, self).__init__(**kwargs)
self.orientation = 'vertical'
class CustomLayout(FloatLayout):
def __init__(self, **kwargs):
# make sure we aren't overriding any important functionality
super(CustomLayout, self).__init__(**kwargs)
with self.canvas.before:
Color(0, 1, 0, 1) # green; colors range from 0-1 instead of 0-255
self.rect = Rectangle(size=self.size, pos=self.pos)
self.bind(size=self._update_rect, pos=self._update_rect)
def _update_rect(self, instance, value):
self.rect.pos = instance.pos
self.rect.size = instance.size
class MainApp(App):
link_buttons = 0
def build(self):
root = RootWidget()
c = CustomLayout()
s = Scrollbox()
root.add_widget(c)
root.add_widget(s)
def on_enter(self):
func = Function()
buttons = func.buttons()
s.add_widget(buttons)
get_buttons = Button(
text='Get links',
size_hint=(1, 0),
pos=(20, 20))
s.add_widget(get_buttons)
get_buttons.bind(on_press=on_enter)
return root
class Function(MainApp):
def buttons(self):
if self.link_buttons == 0:
layout = GridLayout(cols=1, padding=1, spacing=10,
size_hint=(None, None), width=10)
layout.bind(minimum_height=layout.setter('height'))
self.link_buttons += 1
for buttn in range(20):
btn = Button(text='test', size=(200, 50),
size_hint=(None, None))
try:
self.layout.add_widget(btn)
except:
layout.add_widget(btn)
# create a scroll view, with a size < size of the grid
root = ScrollView(size_hint=(None, None), size=(200, 400),
pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False)
root.add_widget(layout)
return root
if __name__=='__main__':
MainApp().run()
You have a few problems:
1) Function inherts from MainApp - don't do that - its weird!!
2) You are recreating the ScrollView on each click
Here is a modified (part of) the source code that worked for me
class MainApp(App):
link_buttons = 0
def build(self):
layout = GridLayout(cols=1, padding=1, spacing=10,
size_hint=(None, None), width=10)
layout.bind(minimum_height=layout.setter('height'))
sv = ScrollView(size_hint=(None, None), size=(200, 400),
pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False)
sv.add_widget(layout)
self.layout = layout
root = RootWidget()
c = CustomLayout()
s = Scrollbox()
root.add_widget(c)
root.add_widget(s)
s.add_widget(sv)
get_buttons = Button(
text='Get links',
size_hint=(1, 0),
pos=(20, 20))
s.add_widget(get_buttons)
get_buttons.bind(on_press=self.buttons)
return root
def buttons(self, btn):
layout = self.layout
self.link_buttons += 1
for buttn in range(20):
btn = Button(text='test', size=(200, 50),
size_hint=(None, None))
self.layout.add_widget(btn)