在 KivyMD 中为 MDTextField 动态设置属性
Dynamically setting attributes to MDTextField in KivyMD
我有下面的代码,可以在 KivyMD 中动态创建一堆文本字段。但是,我需要设置的一个属性 on_text
不会通过 python 接受我的设置(没有抛出错误,调试时只是一个空白字段),但会通过 KV 接受它们。
我的问题是:为什么它不接受我的 on_text 更新,我如何在保持 python/KV 分离的同时以编程方式解决它?
这是 python 代码:
from kivy.clock import mainthread
from kivymd.app import MDApp
from kivymd.icon_definitions import md_icons
from kivymd.uix.textfield import MDTextField
from kivy.uix.screenmanager import Screen, ScreenManager, NoTransition
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivymd.uix.gridlayout import GridLayout
from kivy.lang import Builder
Builder.load_file('./main.kv')
class HomeScreen(Screen):
def build(self):
return HomeScreen()
class PRApp(MDApp):
def build(self):
self.theme_cls.theme_style = "Light"
self.theme_cls.primary_palette = "Gray"
self.sm = ScreenManager(transition=NoTransition())
self.sm.add_widget(HomeScreen(name="home_screen"))
return self.sm
def add_rm_textboxes(self): # sourcery skip: use-fstring-for-concatenation
for i in range(1,21):
textbox = MDTextField(hint_text=str(i)+" RM",mode="fill",helper_text="Enter your TESTED "+str(i)+" RM",helper_text_mode="on_focus")
textbox.on_text = print(textbox.text)
textbox.name = "rm"+str(i)
self.sm.current_screen.ids.pr_grid.add_widget(textbox)
def wait(self):
pass
PRApp().run()
这是我的 KV 代码:
<HomeScreen>:
id: home_screen
BoxLayout:
orientation: 'vertical'
MDBottomNavigation:
id: bottom_nav
MDBottomNavigationItem:
name: 'home_screen'
text: "Home"
icon: 'home'
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "PR!"
anchor_title: 'center'
MDLabel:
text: "This is the home screen"
halign: 'center'
MDBottomNavigationItem:
name: 'routine_screen'
text: "Routines"
icon: 'notebook'
on_tab_press: app.wait()
MDLabel:
text: "Routines"
halign: 'center'
MDBottomNavigationItem:
name: 'profile_screen'
text: "Profile"
icon: 'account-circle-outline'
on_tab_press: app.add_rm_textboxes()
MDLabel:
text: "Profile"
halign: 'center'
MDGridLayout:
id: pr_grid
cols: 2
无论何时 bind a callback to an event or a property that callback is supposed to be a function / method (name) not what it returns. That's why you got None
when you did ,您都可以像 textbox.bind(text = lambda *args : print("test"))
那样做。另请注意,属性 回调与 kivy 中的事件回调不同。
这是该部分的修改版本,
def add_rm_textboxes(self): # sourcery skip: use-fstring-for-concatenation
for i in range(1,21):
textbox = MDTextField(hint_text=str(i)+" RM",mode="fill",helper_text="Enter your TESTED "+str(i)+" RM",helper_text_mode="on_focus")
textbox.bind(text = self.callback_method)
# textbox.bind(text = lambda *args : print("test"))
textbox.name = "rm"+str(i)
self.sm.current_screen.ids.pr_grid.add_widget(textbox)
def callback_method(self, txtbx, txt):
print(f"{txtbx.text = }, {txt = }, {txtbx.name = }")
我有下面的代码,可以在 KivyMD 中动态创建一堆文本字段。但是,我需要设置的一个属性 on_text
不会通过 python 接受我的设置(没有抛出错误,调试时只是一个空白字段),但会通过 KV 接受它们。
我的问题是:为什么它不接受我的 on_text 更新,我如何在保持 python/KV 分离的同时以编程方式解决它?
这是 python 代码:
from kivy.clock import mainthread
from kivymd.app import MDApp
from kivymd.icon_definitions import md_icons
from kivymd.uix.textfield import MDTextField
from kivy.uix.screenmanager import Screen, ScreenManager, NoTransition
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivymd.uix.gridlayout import GridLayout
from kivy.lang import Builder
Builder.load_file('./main.kv')
class HomeScreen(Screen):
def build(self):
return HomeScreen()
class PRApp(MDApp):
def build(self):
self.theme_cls.theme_style = "Light"
self.theme_cls.primary_palette = "Gray"
self.sm = ScreenManager(transition=NoTransition())
self.sm.add_widget(HomeScreen(name="home_screen"))
return self.sm
def add_rm_textboxes(self): # sourcery skip: use-fstring-for-concatenation
for i in range(1,21):
textbox = MDTextField(hint_text=str(i)+" RM",mode="fill",helper_text="Enter your TESTED "+str(i)+" RM",helper_text_mode="on_focus")
textbox.on_text = print(textbox.text)
textbox.name = "rm"+str(i)
self.sm.current_screen.ids.pr_grid.add_widget(textbox)
def wait(self):
pass
PRApp().run()
这是我的 KV 代码:
<HomeScreen>:
id: home_screen
BoxLayout:
orientation: 'vertical'
MDBottomNavigation:
id: bottom_nav
MDBottomNavigationItem:
name: 'home_screen'
text: "Home"
icon: 'home'
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "PR!"
anchor_title: 'center'
MDLabel:
text: "This is the home screen"
halign: 'center'
MDBottomNavigationItem:
name: 'routine_screen'
text: "Routines"
icon: 'notebook'
on_tab_press: app.wait()
MDLabel:
text: "Routines"
halign: 'center'
MDBottomNavigationItem:
name: 'profile_screen'
text: "Profile"
icon: 'account-circle-outline'
on_tab_press: app.add_rm_textboxes()
MDLabel:
text: "Profile"
halign: 'center'
MDGridLayout:
id: pr_grid
cols: 2
无论何时 bind a callback to an event or a property that callback is supposed to be a function / method (name) not what it returns. That's why you got None
when you did textbox.bind(text = lambda *args : print("test"))
那样做。另请注意,属性 回调与 kivy 中的事件回调不同。
这是该部分的修改版本,
def add_rm_textboxes(self): # sourcery skip: use-fstring-for-concatenation
for i in range(1,21):
textbox = MDTextField(hint_text=str(i)+" RM",mode="fill",helper_text="Enter your TESTED "+str(i)+" RM",helper_text_mode="on_focus")
textbox.bind(text = self.callback_method)
# textbox.bind(text = lambda *args : print("test"))
textbox.name = "rm"+str(i)
self.sm.current_screen.ids.pr_grid.add_widget(textbox)
def callback_method(self, txtbx, txt):
print(f"{txtbx.text = }, {txt = }, {txtbx.name = }")