【问题标题】:Kivy: AttributeError: 'super' object has no attribute '__getattr__', having unwanted behavioralKivy: AttributeError: \'super\' object has no attribute \'__getattr__\',有不想要的行为
【发布时间】:2022-10-13 03:09:59
【问题描述】:

有主要错误

第 153 行,在在里面self.ids.date_text.text = str(datetime.now().strftime('%A %d %B %Y')) 文件“kivy\properties.pyx”,第 964 行,位于 kivy.properties.ObservableDict。获取属性AttributeError:“超级”对象没有属性“获取属性'

我想添加我找到的这段代码,但它不起作用。这是我的 main.py

task_list_dialog = None  # Here

# Add the below functions
def show_task_dialog(self):
    if not self.task_list_dialog:
        self.task_list_dialog = MDDialog(
            title="Create Task",
            type="custom",
            content_cls=DialogContent(),
        )

    self.task_list_dialog.open()

    # add this entire function

def on_start(self):
    """Load the saved tasks and add them to the MDList widget when the application starts"""
    try:
        completed_tasks, uncomplete_tasks = db.get_tasks()

        if uncomplete_tasks != []:
            for task in uncomplete_tasks:
                add_task = ListItemWithCheckbox(pk=task[0], text=task[1], secondary_text=task[2])
                self.root.ids.container.add_widget(add_task)

        if completed_tasks != []:
            for task in completed_tasks:
                add_task = ListItemWithCheckbox(pk=task[0], text='[s]' + task[1] + '[/s]',
                                                secondary_text=task[2])
                add_task.ids.check.active = True
                self.root.ids.container.add_widget(add_task)
    except Exception as e:
        print(e)
        pass

def close_dialog(self, *args):
    self.task_list_dialog.dismiss()

def add_task(self, task, task_date):
    '''Add task to the list of tasks'''

    # Add task to the db
    created_task = db.create_task(task.text, task_date)  # Here

    # return the created task details and create a list item
    self.root.get_screen('tasks').ids.container.add_widget(
        ListItemWithCheckbox(pk=created_task[0], text='[b]' + created_task[1] + '[/b]',
                             secondary_text=created_task[2]))  # Here
    task.text = ''

类对话框内容(MDBoxLayout):

def __init__(self, **kwargs):
    super().__init__(**kwargs)
    # set the date_text label to today's date when useer first opens dialog box
    self.ids.date_text.text = str(datetime.now().strftime('%A %d %B %Y'))

def show_date_picker(self):
    """Opens the date picker"""
    date_dialog = MDDatePicker()
    date_dialog.bind(on_save=self.on_save)
    date_dialog.open()

def on_save(self, instance, value, date_range):
    """This functions gets the date from the date picker and converts its it a
    more friendly form then changes the date label on the dialog to that"""

    date = value.strftime('%A %d %B %Y')
    self.ids.date_text.text = str(date)

类 ListItemWithCheckbox(TwoLineAvatarIconListItem): '''自定义列表项'''

def __init__(self, pk=None, **kwargs):
    super().__init__(**kwargs)
    # state a pk which we shall use link the list items with the database primary keys
    self.pk = pk

def mark(self, check, the_list_item):
    '''mark the task as complete or incomplete'''
    if check.active == True:
        # add strikethrough to the text if the checkbox is active
        the_list_item.text = '[s]' + the_list_item.text + '[/s]'
        db.mark_task_as_complete(the_list_item.pk)  # here
    else:
        the_list_item.text = str(db.mark_task_as_incomplete(the_list_item.pk))  # Here

def delete_item(self, the_list_item):
    '''Delete the task'''
    self.parent.remove_widget(the_list_item)
    db.delete_task(the_list_item.pk)  # Here

类 LeftCheckbox(ILeftBodyTouch,MDCheckbox): """自定义左容器"""

这是我的 .kv 文件

 MDBottomNavigationItem:
        name: 'screen 2'
        icon: 'calendar-month-outline'
        MDFloatLayout:
           MDLabel:
              id: task_label
              halign: 'center'
              markup: True
              text: "[u][size=48][b]TASKS[/b][/size][/u]"
              pos_hint: {'y': .45}

           ScrollView:
              pos_hint: {'center_y': .5, 'center_x': .5}
              size_hint: .9, .8

              MDList:
                 id: container

           MDFloatingActionButton:
              icon: 'plus-thick'
              on_release: app.show_task_dialog()
              elevation_normal: 12
              pos_hint: {'x': .8, 'y':.05}
        DialogContent:
           orientation: "vertical"
           spacing: "10dp"
           size_hint: 1, None
           height: "130dp"

           GridLayout:
              rows: 1

              MDTextField:
                 id: task_text
                 hint_text: "Add Task..."
                 pos_hint: {"center_y": .4}
                 max_text_length: 50
                 on_text_validate: (app.add_task(task_text, date_text.text), app.close_dialog())

              MDIconButton:
                 icon: 'calendar'
                 on_release: root.show_date_picker()
                 padding: '10dp'

           MDLabel:
              spacing: '10dp'
              id: date_text

           BoxLayout:
              orientation: 'horizontal'

              MDRaisedButton:
                 text: "SAVE"
                 on_release: (app.add_task(task_text, date_text.text), app.close_dialog())
              MDFlatButton:
                 text: 'CANCEL'
                 on_release: app.close_dialog()
        ListItemWithCheckbox:
           id: the_list_item
           markup: True

           LeftCheckbox:
              id: check
              on_release:
                 root.mark(check, the_list_item)

           IconRightWidget:
              icon: 'trash-can-outline'
              theme_text_color: "Custom"
              text_color: 1, 0, 0, 1
              on_release:
                 root.delete_item(the_list_item)

当我通过评论该函数来运行我的代码时,我也有这种不需要的行为。

unwanted behaivior 有人可以帮我解决一下我的情况吗?谢谢!

【问题讨论】:

  • 运行__init__() 方法时,小部件中的ids 通常尚未分配。您可能会尝试使用Clock.schedule_once() 之类的东西来延迟访问ids
  • 像“Clock.schedule_once(self.__init__(), 3)”之类的东西?
  • 不,您不能延迟__init__() 的执行。创建另一个方法,它将对ids 执行任何您想要的操作,并使用Clock.schedule_once()__init__() 方法中安排该新方法。
  • 我创建了几乎相同的方法,但它没有帮助def _otlozhit(self): self.ids.date_text.text = str(datetime.now().strftime('%A %d %B %Y')) 或者我应该如何访问它们?
  • 你在你的__init__() 方法中使用了Clock.schedule_once(self._otlozhit) 吗?

标签: python kivy kivymd


【解决方案1】:
class DialogContent(MDBoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Clock.schedule_one(self.set_date_text)

    def set_date_text(self., *args):
        self.ids.date_text.text = str(datetime.now().strftime('%A %d %B %Y'))

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 2023-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-01
    • 1970-01-01
    相关资源
    最近更新 更多