i want to add a checkbox to buttons - python

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.checkbox import CheckBox
class Ckbox(BoxLayout):
orientation = "vertical"
cc =[]
def __init__(self):
super().__init__()
for i in range(5):
self.bb = Button()
self.cq = CheckBox()
self.cc.append(self.cq)
self.add_widget(self.bb)
self.add_widget(self.cq)
class Ckboxapp(App):
def build(self):
return Ckbox()
Ckboxapp().run()
from the above code, i get this
but i want the checkbox and button to be together so i add the button variable to the add widget as self.bb.add_widget(self.cq) and got this
the second image show the checkbox attached to the button but only showing on the last button only. i want itlike in the second iamge but i want it to be on all the buttons. what can i do?

If you put each CheckBox/Button pair in another BoxLayout, I think you will get what you want. Try this:
class Ckbox(BoxLayout):
orientation = "vertical"
def __init__(self):
super().__init__()
for i in range(5):
bl = BoxLayout()
bb = Button(text='Button ' + str(i), size_hint_x=0.85)
cq = CheckBox(size_hint_x=0.15)
bl.add_widget(cq)
bl.add_widget(bb)
self.add_widget(bl)

Related

Not able to print the text taken from kivy.uix.textinput.TextInput in KIVY Python

What I want to do is take input from kivy.uix.textinput.TextInput() and show it on the screen.
I am new to gui Programming and I think it is an easy task.
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
class MyWindowApp(App):
def __init__(self):
super(MyWindowApp, self).__init__()
self.lbl = Label(text='Read Me!')
self.inp = TextInput(multiline=False,
size_hint =(1, 0.05),
pos_hint = {"x":0, "y":0.05})
def build(self):
self.inp.bind(on_text_validate=self.on_enter)
#self.bt1.bind(on_press=self.clk)
layout = FloatLayout()
layout.orientation = 'vertical'
layout.add_widget(self.lbl)
layout.add_widget(self.inp)
return layout
def on_enter(self,value):
print(value)
def clk(self, obj):
print ('input')
x = input()
self.lbl.text = x
window = MyWindowApp()
window.run()
when i run the code, I get the regular output output.
when I type say "hello world" in the textbox, this is the output:
<kivy.uix.textinput.TextInput object at 0x03F5AE30>
I do not get what I typed.
please suggest what should I do
Modify the following ...
def on_enter(self, value):
print(value.text)

how to Change colour of a particular button in gridLayout in kivy

I am trying to make tambola coin picker with Python and Kivy and I am new to kivy.
Here, I created gridlayout buttons from 1 to 90. I want to change the color of particular button in gridlayout when its number is picked. I am facing issues to update gridlayout with new colored button. Here I am attaching my code. screenshot
#!/usr/bin/python
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Color
import random
coins = random.sample(range(1,91), 90)
#print(coins)
picked_coins=[]
current_coin=0
#print(picked_coins)
class Housie(FloatLayout):
def __init__(self,**kwargs):
super(Housie,self).__init__(**kwargs)
self.title = Label(text="Housie Coin Picker",font_size = 50,size_hint=(1, .55),pos_hint={'x':0, 'y':.45})
self.main_label = Label(text = "Click PICK NUMBER", size_hint=(1, .60),pos_hint={'x':0, 'y':.35})
self.picked_ones = Label(text = "picked_coins", size_hint=(1, .40),pos_hint={'x':0, 'y':.40})
self.help_button = Button(text = "PICK NUMBER", size_hint=(.3, .1),pos_hint={'x':.65, 'y':.1},on_press = self.update)
self.add_widget(self.title)
self.add_widget(self.main_label)
self.add_widget(self.picked_ones)
self.add_widget(self.help_button)
self.add_widget(self.userinterface())
def userinterface(self):
self.layout = GridLayout(cols = 10,size_hint=(.50, .50))
for i in range(1,91):
self.layout.add_widget(Button(background_color=(1,0,0,1),text =str(i)))
return self.layout
def update(self,event):
for coin in coins:
if coin not in picked_coins:
current_coin=coin
picked_coins.append(coin)
self.main_label.text = str(coin)
for i in self.layout.children:
if i.text == str(coin):
#What to do Here?
break
self.picked_ones.text = "Picked coins = {}".format(" ".join(str(sorted(picked_coins))))
class app1(App):
def build(self):
return Housie()
if __name__=="__main__":
app1().run()
You can bind a method to each Button like this:
def userinterface(self):
self.layout = GridLayout(cols = 10,size_hint=(.50, .50))
for i in range(1,91):
self.layout.add_widget(Button(background_color=(1,0,0,1),text=str(i), on_release=self.butt_pressed))
return self.layout
def butt_pressed(self, button):
button.background_normal = ''
button.background_color = (1,0,0,1)
Th butt_pressed() method changes the background color of the pessed Button.

Reference objects in kivy added with python

I need to know how to reference dynamically created objects. Like in the example, how can I change text of the buttons after creation? Normaly I would do it using their ids, but as far as I know, you can't give ids to objects created in python.
.py code
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.button import Button
from kivy.clock import mainthread
NUMBER_OF_BUTTONS = 5
class MapScreen(Screen):
#mainthread
def on_enter(self):
for i in range(NUMBER_OF_BUTTONS):
button = Button(text="B_" + str(i))
self.ids.grid.add_widget(button)
class Test(App):
pass
Test().run()
.kv code
ScreenManager:
MapScreen:
<MapScreen>:
name: 'map'
GridLayout:
id: grid
cols: 1
You could just keep a list of the Buttons:
def on_enter(self):
self.buttons = []
for i in range(NUMBER_OF_BUTTONS):
button = Button(text="B_" + str(i))
self.buttons.append(button)
self.ids.grid.add_widget(button)
or you could create your own dictionary:
def on_enter(self):
self.buttons = {}
for i in range(NUMBER_OF_BUTTONS):
text = "B_" + str(i)
button = Button(text=text)
self.buttons[text] = button
self.ids.grid.add_widget(button)

Kivy Popup Dynamic Height

I'm looking to make a popup on the python-side that has a dynamic height.
So far, I have this within the screens __init__ class. The kv file has another widget that called the popup on_release. Anyways, I have found that this produces a popup with very wonky formatting:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import Screen, ScreenManager
kv = '''
ScreenManagement:
id: 'manager'
BrokenPopup:
name: 'broken'
manager: 'manager'
<BrokenPopup>:
BoxLayout:
Button:
text: 'Test'
on_release: root.p.open()
'''
class ScreenManagement(ScreenManager):
pass
class BrokenPopup(Screen):
def __init__(self, **kwargs):
super(BrokenPopup,self).__init__(**kwargs)
self.p = Popup(auto_dismiss=False, size_hint_x=.6, size_hint_y=None, title='A popup')
self.g = GridLayout(cols=1, spacing=10)
self.g.add_widget(Button(text='Test1', size_hint_y=None, height=32))
self.g.add_widget(Button(text='Test2', size_hint_y=None, height=32))
self.g.bind(minimum_height=self.g.setter('height'))
self.p.add_widget(self.g)
self.p.bind(height=self.g.setter('height')) #<- this does not work to change the popup height!
class TheApp(App):
def build(self):
return Builder.load_string(kv)
TheApp().run()
The popup size is set to fit only one widget, leaving the second button (and all others that may be included) to float beyond the confines of the popup border.
How should I change the code so that all of the widgets fit within the confines of the popup? I am trying to do that by dynamically setting the height of the popup, however that is not proving effective.
I have modified your code to do what I think you want. Basically it adds the minimum_height from the GridLayout, that is added to your Popup, to the calculated height of the title and the dividing bar. The first Button in the GridLayout now adds another Button to the GridLayout for testing.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import Screen, ScreenManager
kv = '''
ScreenManagement:
id: 'manager'
BrokenPopup:
name: 'broken'
manager: 'manager'
<BrokenPopup>:
BoxLayout:
Button:
text: 'Test'
on_release: root.p.open()
'''
class ScreenManagement(ScreenManager):
pass
class BrokenPopup(Screen):
def __init__(self, **kwargs):
super(BrokenPopup,self).__init__(**kwargs)
self.popup_title_height = None
self.p = Popup(auto_dismiss=False, size_hint_x=.6, size_hint_y=None, title='A popup')
self.g = GridLayout(cols=1, spacing=10)
self.g.bind(minimum_height=self.fix_size)
self.g.add_widget(Button(text='Test1', size_hint_y=None, height=32, on_release=self.add_one))
self.g.add_widget(Button(text='Test2', size_hint_y=None, height=32))
self.p.add_widget(self.g)
def add_one(self, *args):
self.g.add_widget(Button(text='Another', size_hint_y=None, height=32))
def get_popup_title_height(self):
height = 0
popupGrid = self.p.children[0]
height += popupGrid.padding[1] + popupGrid.padding[3]
for child in popupGrid.children:
if isinstance(child, BoxLayout):
continue
else:
height += child.height + popupGrid.spacing[1]
self.popup_title_height = height
def fix_size(self, *args):
if self.popup_title_height is None:
self.get_popup_title_height()
self.p.height = self.g.minimum_height + self.popup_title_height
class TheApp(App):
def build(self):
return Builder.load_string(kv)
TheApp().run()
I cheated a bit by looking at the code for Popup and the style.kv file to see how the Popup is displayed. So, if any of that is changed, this may not work.
I have found a solution for my original problem that is influenced by John Anderson's answer. I'll provide a walkthrough below for how I came to this solution.
1) Here's a photo of my original problem; I needed to dynamically set the popup height based on the widgets that are assigned to it. Before finding the below solution, my popup looked like this with the code in the OP:
As you can see, the widgets go beyond the borders of the popup.
2) I found something interesting while looking inside the popup widget with the inspector tool.
python '/path/to/your/file.py' -m inspector
Using control-e, I can click widgets and inspect their attributes. I clicked the popup button and cycled through the parent widgets until I found the popup widget.
As you can see in the photo, the popup widget has one child: a grid layout. Here are the children of that grid layout:
Interestingly, the grid layout contains:
One label, with a height of 33
One line, with a height of 4
A box layout, which contains the contents of the popup
2 units of spacing between these three widgets
12 units of padding all-around; so 24 additional units to consider for the height
3) In my solution, I have hard-written the default heights of the label, the line widget, and all default popup spacing and padding. Then, I cycle through the children inside the box layout, and add their heights. I also add 10 to those children heights, as the gridlayout that contains all of these widgets uses a spacing of 10.
Solution:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import Screen, ScreenManager
kv = '''
ScreenManagement:
id: 'manager'
BrokenPopup:
name: 'broken'
manager: 'manager'
<BrokenPopup>:
BoxLayout:
Button:
text: 'Test'
on_release: root.p.open()
'''
class ScreenManagement(ScreenManager):
pass
class BrokenPopup(Screen):
def __init__(self, **kwargs):
super(BrokenPopup,self).__init__(**kwargs)
self.p = Popup(auto_dismiss=False, size_hint_x=.6, size_hint_y=None, title='A popup')
self.g = GridLayout(cols=1, spacing=10, padding=[0,10,0,-5])
self.g.bind(minimum_height=self.fix_popup_height) # <- here's the magic
self.g.add_widget(Button(text='Test1', size_hint_y=None, height=32))
self.g.add_widget(Button(text='Test2', size_hint_y=None, height=32))
self.p.add_widget(self.g)
def fix_popup_height(self, grid, *args):
# a generalized function that, when bound to minimum_height for a grid with popup widgets,
# this will set the height of the popup
height = 0
height += 33 # for popup label
height += 4 # for popup line widget
height += 24 # for popup padding
height += 2 # for spacing between main popup widgets
for child in grid.children:
height += child.height + 10 # adds 10 for the spacing between each child
grid.parent.parent.parent.height = height # sets popup height
pass
class TheApp(App):
def build(self):
return Builder.load_string(kv)
TheApp().run()
Notable changes from the OP:
Bind the minimum_height of the widget container to the fix_popup_height() function; this will trigger each time a widget is added to the popup.
Declare the fix_popup_height() within the screen class.
Here's the fixed popup:

Create kivy dropdown list but only a part of them can be opened

I am using kivy as my GUI tools for my python program.
when I want to create a table,in which there is a column containing dropdown list to make select value easier.
However, I can not make it works correctly.
The following is my code.
import kivy
kivy.require('1.10.0')
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.gridlayout import GridLayout
sel =["A","B","C"]
class MyGrid(GridLayout):
def __init__(self, **kwargs):
super(MyGrid, self).__init__(**kwargs)
self.redraw()
def redraw(self):
self.clear_widgets()
self.rows = 5
self.cols =2
for i in range(5):
label = Label(text="cell"+str(i+1))
self.add_widget(label)
drpName = DropDown()
btnName = Button(text="B",size_hint=(None, None))
for e in sel:
btn=Button(text=e, size_hint_y=None, height=btnName.height)
btn.bind(on_release=lambda btn:drpName.select(btn.text))
drpName.add_widget(btn)
btnName.bind(on_release=drpName.open)
drpName.bind(on_select=lambda instance, x: setattr(btnName, 'text', x))
self.add_widget(btnName)
class testApp(App):
def build(self):
return MyGrid()
if __name__=="__main__":
testApp().run()
Only a part of button open the pull down list and all of the selected value will replace the text of last button.
Could you help me out. Thanks in advance.
After reading post Python Lambda in a loop[Building Dropdowns Dynamically in Kivy, I can make my program works.
Thanks for valuable post.
import kivy
kivy.require('1.10.0')
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.gridlayout import GridLayout
sel =["A","B","C"]
class MyGrid(GridLayout):
def __init__(self, **kwargs):
super(MyGrid, self).__init__(**kwargs)
self.redraw()
def redraw(self):
self.clear_widgets()
self.rows = 5
self.cols =2
drpName = []
for i in range(5):
label = Label(text="cell"+str(i+1))
self.add_widget(label)
drpName.append(DropDown())
btnName=Button(text="B",size_hint=(None, None))
for e in sel:
btn=Button(text=e, size_hint_y=None, height=btnName.height)
btn.bind(on_release=lambda btn=btn,dropdown=drpName[i]:dropdown.select(btn.text))
drpName[i].add_widget(btn)
btnName.bind(on_release=drpName[i].open)
drpName[i].bind(on_select=lambda instance, x,btn=btnName: setattr(btn, 'text', x))
self.add_widget(btnName)
class testApp(App):
def build(self):
return MyGrid()
if __name__=="__main__":
testApp().run()

Categories