我不知道如何在 KivyMD 中更改
MDSegmentedControl
的活动(选定)段而不触摸它(例如,在从数据库加载数据并打开屏幕后)。我可以将 current_active_segment
属性设置为 MDSegmentedControlItem
之一,但它对 UI 没有影响。示例代码如下:
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.metrics import dp
from kivy.input.providers.mouse import MouseMotionEvent
from kivy.clock import Clock
kvFloatLayout = """
MDScreen:
id: mdscr
MDBoxLayout:
orientation: "vertical"
adaptive_height: True
pos_hint: {"top": 1}
spacing: "12dp"
MDTopAppBar:
id: top_app_bar
pos_hint: {"top": 1}
title: "Test App"
elevation: 4
MDBoxLayout:
orientation: "vertical"
adaptive_height: True
pos_hint: {"top": 1}
padding: "12dp", "0dp", "12dp", "12dp"
spacing: "12dp"
MDRaisedButton:
id: btn_resize
text: "Resize"
on_release: app.seg_resize()
MDRaisedButton
id: btn_change
text: "Change selection"
on_release: app.seg_change_selection()
MDSegmentedControl:
id: seg_options
MDSegmentedControlItem:
id: sci_option1
text: "Option left"
MDSegmentedControlItem:
id: sci_option2
text: "Option right"
"""
class TestApp(MDApp):
def build(self):
return Builder.load_string(kvFloatLayout)
def seg_resize(self):
#Workaround from stackoverflow (size not working in .kv - https://stackoverflow.com/questions/74999000/kivymd-mdsegmentedcontrol-size)
self.root.ids.seg_options.ids.segment_panel.width = (Window.width - dp(24))
def seg_change_selection(self):
sc = self.root.ids.seg_options
print("---sc:")
print(sc)
sci = self.root.ids.sci_option2
print("---sci:")
print(sci)
print("---sc.current_active_segment before:")
print(sc.current_active_segment)
sc.current_active_segment = sci
print("---sc.current_actilve_segment after:")
print(sc.current_active_segment.text)
#A poor workaround with mouse click:
#Clock.schedule_once(self.simulate_mouse_click, 1)
def simulate_mouse_click(self, *args):
x = 0.75*Window.width
y = Window.height - \
self.root.ids.top_app_bar.height - \
self.root.ids.btn_resize.height - \
self.root.ids.btn_change.height - \
dp(12) * 3 - 40
touch = MouseMotionEvent(None, 0, (x,y)) # args are device, id, spos
touch.button = 'left'
touch.pos = (x,y)
touch.x = touch.px = touch.ox = x
touch.y = touch.py = touch.oy = y
print("---touch")
print(str(touch))
Window.dispatch('on_touch_down', touch)
#1/0
TestApp().run()
有什么想法或解决方法吗?
我能够使其工作的唯一方法是在右侧的分段项目上单击鼠标,但这当然远不是一个良好且可靠的解决方案。就是这部分代码:
#Clock.schedule_once(self.simulate_mouse_click, 1)
不幸的是,
MDSegmentedControl
的设计者似乎并没有考虑到您想要的实用程序。另一种欺骗 MDSegmentedControl
使其认为已被单击的方法是创建一个 FakeTouch
类:
class FakeTouch(object):
pass
然后,在您的
seg_change_selection()
方法中使用该类:
def seg_change_selection(self):
sc = self.root.ids.seg_options
print("---sc:")
print(sc)
sci = self.root.ids.sci_option2
print("---sci:")
print(sci)
print("---sc.current_active_segment before:")
print(sc.current_active_segment)
# sc.current_active_segment = sci
touch = FakeTouch()
touch.x = sci.center_x
touch.y = sci.center_y
sc.on_press_segment(sci, touch)
print("---sc.current_actilve_segment after:")
print(sc.current_active_segment.text)
# A poor workaround with mouse click:
# Clock.schedule_once(self.simulate_mouse_click, 1)
与模拟鼠标点击类似,但可能更简单。