kivy - 如何在具有重叠小部件的应用程序中分离 kivy 中的触摸
问题描述
我正在制作钢琴应用程序,但无法分开触摸。只是为了说明,我使用了 KivyMD。
这是我正在使用的结构:
enter<MainScreen>:
name: 'main'
MDFloatLayout:
MDStackLayout:
id: white_notes_layout
padding: '0dp'
spacing: '0dp'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
MDFloatLayout:
id: black_notes_layout code here
white_notes_layout 将拥有钢琴的所有白键,而 black_notes_layout 将拥有所有黑键。
下面是我用来获取按钮的代码。
white_notes = 包含白键音符的音频文件名称的列表 [共 8 个]
black_notes = 包含白键音符的音频文件名称的列表 [共 5 个]
notes_loaded = 包含使用 SoundLoader 加载的两种类型音符的声音的列表 [前 8 个white_notes 和 black_notes 的索引]
class MainScreen(MDScreen):
def on_enter(self, *args):
# White Keys' generation
for note in white_notes:
NoteButton=Factory.MDFlatButton(size_hint=(1,0.125))
self.ids[note]=NoteButton
NoteButton.name=note
NoteButton.bind(on_press=self.play_note)
self.ids.white_notes_layout.add_widget(NoteButton)
#Black Keys' generation
count=1 #used to skip one position
top_position=1 # used to change 'top' pos_hint of black keys in floatlayout
note_index=0 # used to stop while loop after all black keys are inserted
while note_index<len(black_notes):
note=black_notes[note_index]
if count!=3:
top_position-=0.08
NoteButton=Factory.MDRaisedButton(size_hint=(0.65,0.09), pos_hint={'right':1, 'top':top_position})
NoteButton.md_bg_color=(0,0,0,1)
NoteButton.name=note
NoteButton.bind(on_press=self.play_note)
self.ids.black_notes_layout.add_widget(NoteButton)
top_position-=0.045
count+=1
note_index+=1
else:
top_position-=0.08
top_position-=0.045
count=0
def on_leave(self, *args):
self.ids.white_notes_layout.remove_widget(self.ids.white_notes_layout.children[0])
def play_note(self, button, *args):
note=button.name
if note in black_notes:
note=self.notes_loaded[black_notes.index(note)+len(white_notes)]
elif note in white_notes:
note=self.notes_loaded[white_notes.index(note)]
if note:
note.volume=note_volume
note.play()
这是它的外观:
如您所见,黑键与白键重叠。因此,当按下黑键时,也会按下白键。我尝试使用 collide_points 进行碰撞检测,但遇到了以下问题:
- 我尝试使用带有自定义 on_press 的自定义按钮。但我无法获得触摸位置,on_touch_down 确实有触摸位置,但我无法在 on_press 中获得它。那么我如何在 on_press 中获得“触摸”。
- 进行碰撞时,我需要检查该点是否在任何黑键中。所以,我需要 black_key.collide_point()。由于我为白色按钮创建了另一个类,因此我尝试使用以下方法获取黑键:
for child in app.ids.black_notes_layout.children
为此,我需要 python 文件中的“应用程序”。所以我做到了app = MDApp.get_running_app()
,但这显示“无类型对象没有属性 ID”错误。然后我从 kivy.app 导入 App 并尝试 App.get_running_app() 但再次失败。
所以请告诉这两个问题的解决方案:
1.如何联系on_press()
2.如何获取应用程序的所有ID。
或者告诉我可以解决这个问题的替代方法。(尽可能不改变应用程序的结构)
解决方案
推荐阅读
- python - HTTP 代理以即时修改传出的 HTTP 请求
- javascript - 使用 react-router-dom 链接到特定的 mui-tab
- r - 在R中压缩字符串
- c# - C# 单元测试 - 实际:(null) 使用 xUnit 中的 List 和 Moq 框架的结果
- ajax - 从具有动态 ID 的按钮获取 ID
- javascript - AngularJS + Select2(多个 - 标签) - 有时会显示其他标签
- c# - LazyLoadingEnabled false 不起作用
- asp.net-web-api - 为什么这个 RestSharp 文件上传不起作用?
- javascript - 在 android 设备上运行 expo 应用程序时网络请求失败
- assembly - RISC-V 使用 LUI 和 ADDI 构建 32 位常量