Python 为KivyMD中的图标提供函数

Python 为KivyMD中的图标提供函数,python,kivy,icons,textfield,kivy-language,Python,Kivy,Icons,Textfield,Kivy Language,我想给文本字段中输入的图标一个函数,我想给它一个典型的函数,它有一个“眼睛关闭”的密码图标,当你按下图标时,将函数“密码”更改为False,图标更改为“眼睛打开”,如果我再次按下,将更改为True,图标返回到“眼睛关闭”,让我解释一下,这是我的主要代码: from kivymd.app import MDApp from kivymd.uix.screen import Screen from kivymd.uix.button import MDRectangleFlatButton, MDI

我想给文本字段中输入的图标一个函数,我想给它一个典型的函数,它有一个“眼睛关闭”的密码图标,当你按下图标时,将函数“密码”更改为False,图标更改为“眼睛打开”,如果我再次按下,将更改为True,图标返回到“眼睛关闭”,让我解释一下,这是我的主要代码:

from kivymd.app import MDApp
from kivymd.uix.screen import Screen
from kivymd.uix.button import MDRectangleFlatButton, MDIconButton
from kivy.lang import Builder
from helpers import *



class DemoApp(MDApp):

    def build(self):
        screen = Screen()
        self.theme_cls.primary_palette = 'Yellow'
        self.theme_cls.theme_style = 'Dark'

        btn = MDRectangleFlatButton(text='Confirmar', pos_hint= {'center_x': 0.5, 'center_y': 0.35},
                                    on_release= self.show_data)

        self.username = Builder.load_string(username_helper)
        self.contraseña = Builder.load_string(contraseña_helper)

        screen.add_widget(self.username)
        screen.add_widget(self.contraseña)
        screen.add_widget(btn)
        return screen

    def show_data(self, obj):
        print(f'Usuario: {self.username.text}\nContraseña: {self.contraseña.text}')

if __name__=='__main__':
    DemoApp().run()
在这里,我的文件处于字符串模式,这是我导入的helpers模块:

username_helper = '''
MDTextField:
    hint_text: 'Usuario'
    required: True
    helper_text: 'Enter text'
    helper_text_mode: 'on_error'
    pos_hint: {'center_x': 0.5, 'center_y': 0.5}
    size_hint_x: None
    width: 200
'''

contraseña_helper = '''
MDTextField:
    hint_text: 'Contraseña'
    password: True
    icon_right: "eye-off"
    pos_hint: {'center_x': 0.5, 'center_y':0.43}
    size_hint_x: None
    width: 200
'''

在这种配置下,当键入密码时,一些字符串显示为星号,但我希望通过按下右侧的“眼睛离开”图标,我可以看到我正在键入的字符串,如果我再次按下它,则用“*”隐藏,以此类推。

您可以通过扩展
MDTextField
这样做:

class MyMDTextField(MDTextField):
    password_mode = BooleanProperty(True)

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            if self.icon_right:
                # icon position based on the KV code for MDTextField
                icon_x = (self.width + self.x) - (self._lbl_icon_right.texture_size[1]) - dp(8)
                icon_y = self.center[1] - self._lbl_icon_right.texture_size[1] / 2
                if self.mode == "rectangle":
                    icon_y -= dp(4)
                elif self.mode != 'fill':
                    icon_y += dp(8)

                # not a complete bounding box test, but should be sufficient
                if touch.pos[0] > icon_x and touch.pos[1] > icon_y:
                    if self.password_mode:
                        self.icon_right = 'eye'
                        self.password_mode = False
                        self.password = self.password_mode
                    else:
                        self.icon_right = 'eye-off'
                        self.password_mode = True
                        self.password = self.password_mode

                    # try to adjust cursor position
                    cursor = self.cursor
                    self.cursor = (0,0)
                    Clock.schedule_once(partial(self.set_cursor, cursor))
        return super(MyMDTextField, self).on_touch_down(touch)

    def set_cursor(self, pos, dt):
        self.cursor = pos
这超越了
MDTextField
on\u touch\u down()
方法,并检查图标附近是否有触摸。如果是,则切换图标和
MDTextField
password
设置

您可以在您的
kv
中使用此选项:

contraseña_helper = '''
MyMDTextField:
    hint_text: 'Contraseña'
    password: True
    icon_right: "eye-off"
    pos_hint: {'center_x': 0.5, 'center_y':0.43}
    size_hint_x: None
    width: 200
'''

您可以通过如下方式扩展
MDTextField
来实现:

class MyMDTextField(MDTextField):
    password_mode = BooleanProperty(True)

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            if self.icon_right:
                # icon position based on the KV code for MDTextField
                icon_x = (self.width + self.x) - (self._lbl_icon_right.texture_size[1]) - dp(8)
                icon_y = self.center[1] - self._lbl_icon_right.texture_size[1] / 2
                if self.mode == "rectangle":
                    icon_y -= dp(4)
                elif self.mode != 'fill':
                    icon_y += dp(8)

                # not a complete bounding box test, but should be sufficient
                if touch.pos[0] > icon_x and touch.pos[1] > icon_y:
                    if self.password_mode:
                        self.icon_right = 'eye'
                        self.password_mode = False
                        self.password = self.password_mode
                    else:
                        self.icon_right = 'eye-off'
                        self.password_mode = True
                        self.password = self.password_mode

                    # try to adjust cursor position
                    cursor = self.cursor
                    self.cursor = (0,0)
                    Clock.schedule_once(partial(self.set_cursor, cursor))
        return super(MyMDTextField, self).on_touch_down(touch)

    def set_cursor(self, pos, dt):
        self.cursor = pos
这超越了
MDTextField
on\u touch\u down()
方法,并检查图标附近是否有触摸。如果是,则切换图标和
MDTextField
password
设置

您可以在您的
kv
中使用此选项:

contraseña_helper = '''
MyMDTextField:
    hint_text: 'Contraseña'
    password: True
    icon_right: "eye-off"
    pos_hint: {'center_x': 0.5, 'center_y':0.43}
    size_hint_x: None
    width: 200
'''

只有一个问题,当我在asteriks模式下写入密码时,如果我按下eye图标以显示不带asteriks的密码,则在asteriks no上的位置会显示一行,该行指示您正在写入的位置,该行位于带字母的密码位置,因此我看到了带字母的密码上方的行。我不知道我是否会解释我会附上“之前-之后”的图片,以便更好地向您展示我试图解释的内容:这是
TextInput
中的一个错误。您知道如何修复它吗?我实际上已经看过了代码,
TextInput
中的许多可能设置使得计算光标位置非常复杂。我无法找到解决方法。只有一个问题,当我在asteriks模式下写入密码时,如果我按eye图标向我显示没有asteriks的密码,则在asteriks上的位置会显示指示您写入位置的行。no,在带有字母的密码位置,因此我会看到密码上方带有字母的行。我不知道我是否会解释我会附上“之前-之后”的图片,以便更好地向您展示我试图解释的内容:这是
TextInput
中的一个错误。您知道如何修复它吗?我实际上已经看过了代码,
TextInput
中的许多可能设置使得计算光标位置非常复杂。我没能想出一个解决办法。