kivy:严重对齐窗口小部件从基类

问题描述:

实施例的代码片段:kivy:严重对齐窗口小部件从基类

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 

的内容被显示在该对话框:

enter image description here

我有两个问题。首先:为什么文本与中心对齐?我已经为标签和纹理尺寸设置了绝对尺寸,并设置了halign ='left'。但文字仍与中心保持一致。为什么?

第二:我希望标签可以点击/触摸。例如。应该通过触摸相应的标签来选择复选框。每当我点击一个标签或复选框时,会打印:

(<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">) 

实际上,点击哪里并不重要。即使我在GridLayout之外单击,总是所有标签都会触发触摸事件。但为什么?我只想要我的手指下的那个。

感谢

第一:为什么文本对齐中心? I 已经为标签及其纹理 尺寸设置了绝对尺寸,并设置了halign ='left'。但文字仍与 中心对齐。为什么?

您正在设置texture_size,但是您设置了text_size而不是text_size

第二:我希望标签可以点击/触摸。例如。应通过触摸相应的标签来选择 复选框。 每当我点击一个标签或复选框,这是打印:

在基维的每个部件接收触摸事件。您should检查手动触摸是否发生在您的标签内:

def on_touch_down(self, touch): 
    if self.collide_point(*touch.pos): 
     # The touch has occurred inside the widgets area. Do stuff! 
     pass 
+0

第一个问题回答了100%。关于第二个问题:我试图使用collide_point,但它不起作用。主窗口里面有一个弹出窗口,然后它有一些boxlayouts,然后是一个ScrollView,在ScrollView里面有这些标签。我不确定如何在检查碰撞点之前转换触摸位置坐标。 – nagylzs

+1

当您的小部件使用某些翻译/上下文操作(相对布局/滚动视图...)时,您可能需要使用'Widgets'' to_local','to_widget','to_screen'方法将坐标转换为正确的坐标系。我没有看到任何代码要求在你发布的内容中,但也许我们没有完整的故事。 – Tshirtman

+0

最后我可以让它工作。我必须应用这些转换两次,因为scrollview是在一个对话框中。 – nagylzs

以下是对第二个问题的回答。

默认情况下,触摸事件被分派到当前显示的所有 部件。这意味着小部件在其物理区域内是否发生 而接收到触摸事件。

为了提供最大的灵活性,基维将 事件分派给所有小部件,并让他们决定如何对它们做出反应。 如果你只是想响应触摸小部件内的事件,你 只需检查:

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)