Reputation: 4180
Example code fragment from a base class:
def build_extra_content(self):
grp = 'choice_dialog'
extra_content = GridLayout(cols=2)
lb_width = self.width - 2 * self.choice_height
for choice in self.choices:
cb = CheckBox(group=grp,
size_hint=(None, None), size=(self.choice_height, self.choice_height))
lb = Label(markup=True, text=choice, halign='left', valign='middle',
size_hint=(None, None), size=(lb_width, self.choice_height))
lb.texture_size = (lb_width, self.choice_height)
extra_content.add_widget(cb)
extra_content.add_widget(lb)
# TODO: check the checkbox when the label is touched.
def _lb_press(*args):
print(args)
cb.bind(on_touch_down=_lb_press)
return extra_content
The content is displayed in this dialog:
I have two questions. First: why the text is aligned to the center? I have already set absolute sizes for both the label and its texture size, and set halign='left'. But the text is still aligned to the center. Why?
Second: I wanted the labels to be clickable/touchable. E.g. the checkboxes should be selected by touching their corresponding labels. Whenever I click on a single label or checkbox, this is printed:
(<kivy.uix.checkbox.CheckBox object at 0x0B2C01B8>, <MouseMotionEvent button="left" device="mouse" double_tap_time="0" dpos="(0.0, 0.0)" dsx="0.0" dsy="0.0" dsz="0.0" dx="0.0" dy="0.0" dz="0.0" grab_current="None" grab_exclusive_class="None" grab_list="[]" grab_state="False" id="mouse3" is_double_tap="False" is_mouse_scrolling="False" is_touch="True" is_triple_tap="False" opos="(644.0, 379.0)" osx="0.503125" osy="0.47375" osz="0.0" ox="644.0" oy="379.0" oz="0.0" pos="(644.0, 379.0)" ppos="(644.0, 379.0)" profile="['pos', 'button']" psx="0.503125" psy="0.47375" psz="0.0" push_attrs="('x', 'y', 'z', 'dx', 'dy', 'dz', 'ox', 'oy', 'oz', 'px', 'py', 'pz', 'pos')" push_attrs_stack="[]" px="644.0" py="379.0" pz="0.0" shape="None" spos="(0.503125, 0.47375)" sx="0.503125" sy="0.47375" sz="0.0" time_end="-1" time_start="1507722998.229789" time_update="1507722998.229789" triple_tap_time="0" ud="{}" uid="3" x="644.0" y="379.0" z="0.0">)
(<kivy.uix.checkbox.CheckBox object at 0x0B5FC2D0>, <MouseMotionEvent button="left" device="mouse" double_tap_time="0" dpos="(0.0, 0.0)" dsx="0.0" dsy="0.0" dsz="0.0" dx="0.0" dy="0.0" dz="0.0" grab_current="None" grab_exclusive_class="None" grab_list="[]" grab_state="False" id="mouse3" is_double_tap="False" is_mouse_scrolling="False" is_touch="True" is_triple_tap="False" opos="(644.0, 379.0)" osx="0.503125" osy="0.47375" osz="0.0" ox="644.0" oy="379.0" oz="0.0" pos="(644.0, 379.0)" ppos="(644.0, 379.0)" profile="['pos', 'button']" psx="0.503125" psy="0.47375" psz="0.0" push_attrs="('x', 'y', 'z', 'dx', 'dy', 'dz', 'ox', 'oy', 'oz', 'px', 'py', 'pz', 'pos')" push_attrs_stack="[]" px="644.0" py="379.0" pz="0.0" shape="None" spos="(0.503125, 0.47375)" sx="0.503125" sy="0.47375" sz="0.0" time_end="-1" time_start="1507722998.229789" time_update="1507722998.229789" triple_tap_time="0" ud="{}" uid="3" x="644.0" y="379.0" z="0.0">)
(<kivy.uix.checkbox.CheckBox object at 0x0B5F3768>, <MouseMotionEvent button="left" device="mouse" double_tap_time="0" dpos="(0.0, 0.0)" dsx="0.0" dsy="0.0" dsz="0.0" dx="0.0" dy="0.0" dz="0.0" grab_current="None" grab_exclusive_class="None" grab_list="[]" grab_state="False" id="mouse3" is_double_tap="False" is_mouse_scrolling="False" is_touch="True" is_triple_tap="False" opos="(644.0, 379.0)" osx="0.503125" osy="0.47375" osz="0.0" ox="644.0" oy="379.0" oz="0.0" pos="(644.0, 379.0)" ppos="(644.0, 379.0)" profile="['pos', 'button']" psx="0.503125" psy="0.47375" psz="0.0" push_attrs="('x', 'y', 'z', 'dx', 'dy', 'dz', 'ox', 'oy', 'oz', 'px', 'py', 'pz', 'pos')" push_attrs_stack="[]" px="644.0" py="379.0" pz="0.0" shape="None" spos="(0.503125, 0.47375)" sx="0.503125" sy="0.47375" sz="0.0" time_end="-1" time_start="1507722998.229789" time_update="1507722998.229789" triple_tap_time="0" ud="{}" uid="3" x="644.0" y="379.0" z="0.0">)
Actually it doesn't matter where I click. Even if I click outside the GridLayout, always all labels will trigger the touch event. But why? I only want the one under my finger.
Thanks
Upvotes: 1
Views: 333
Reputation: 16031
Here is the answer to your second question.
By default, touch events are dispatched to all currently displayed widgets. This means widgets receive the touch event whether it occurs within their physical area or not.
In order to provide the maximum flexibility, Kivy dispatches the events to all the widgets and lets them decide how to react to them. If you only want to respond to touch events inside the widget, you simply check:
class ProjectSelectButton(Button):
def click_on_button(self, instance, touch, *args):
print(instance)
if self.collide_point(*touch.pos):
if touch.button == 'right':
print(self.id, "right mouse clicked")
elif touch.buttom == 'left':
print(self.id, "left mouse clicked")
return True
return super(ProjectSelectButton, self).on_touch_down(touch)
Upvotes: 0
Reputation: 39546
First: why the text is aligned to the center? I have already set absolute sizes for both the label and its texture size, and set halign='left'. But the text is still aligned to the center. Why?
You're setting texture_size
, but you should set text_size
instead.
Second: I wanted the labels to be clickable/touchable. E.g. the checkboxes should be selected by touching their corresponding labels. Whenever I click on a single label or checkbox, this is printed:
In Kivy every widget receive touch event. You should check if touch happened inside your label manually:
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
# The touch has occurred inside the widgets area. Do stuff!
pass
Upvotes: 1