Python/kivy-TypeError:';kivy.properties.ObjectProperty';对象是不可编辑的

Python/kivy-TypeError:';kivy.properties.ObjectProperty';对象是不可编辑的,python,kivy,kivy-language,Python,Kivy,Kivy Language,所以我一直在为我的项目制作掷骰子,我称之为:地牢主人的助手,因为他帮助我DM,但现在让我们谈谈我的问题 当我按下按钮RollDice时,它应该接受两个文本输入(骰子的类型和数量)和RollDice,然后立即在控制台中打印骰子的数量和类型以及结果。然而,这反而使程序崩溃 这是相关的python代码(如果需要,可以显示更多): 下面是调用上述函数的按钮: Button: id: RollDice text: "Roll dice" pos_hint: {"top":0.3,"

所以我一直在为我的项目制作掷骰子,我称之为:地牢主人的助手,因为他帮助我DM,但现在让我们谈谈我的问题

当我按下按钮RollDice时,它应该接受两个文本输入(骰子的类型和数量)和RollDice,然后立即在控制台中打印骰子的数量和类型以及结果。然而,这反而使程序崩溃

这是相关的python代码(如果需要,可以显示更多):

下面是调用上述函数的按钮:

Button:
    id: RollDice
    text: "Roll dice"
    pos_hint: {"top":0.3,"x":0}
    size_hint: 0.4, 0.2
    background_color: 0,0,0,0.1
    color: 0,0,0,1
        on_release:
            root.rolldice()
正如我所说并展示的,应该发生的是,它应该打印例如6D6,然后打印这些骰子卷的总数。但是,会发生以下情况(错误代码):


该值由同一屏幕上的两个文本输入框设置:kv文件中的链接


您使用的属性错误,必须在类级别声明它们:

class DiceRoller(Screen):
    diceNumber = ObjectProperty()
    diceType = ObjectProperty()

    def rolldice(self):
        print(F"{self.diceNumber}D{self.diceType}")
        # etc.

在以您的方式访问它们之前,您还需要将它们设置为实际值,但我假设您没有显示的代码中包含了这一点。

您使用的属性错误,必须在类级别声明它们:

class DiceRoller(Screen):
    diceNumber = ObjectProperty()
    diceType = ObjectProperty()

    def rolldice(self):
        print(F"{self.diceNumber}D{self.diceType}")
        # etc.
在以这种方式访问它们之前,您还需要将它们设置为实际值,但我假设您没有显示的代码已经涵盖了这一点。

Problem-ObjectProperty@method level 参考您提供的原始代码,即在方法级别声明的
ObjectProperty

根本原因 原因是,当您将
TextInput
小部件链接到kv文件中的属性时,Kivy将在关联的类/小部件中查找这些属性。如果类/小部件没有具有给定名称的属性,将自动创建
ObjectProperty
,并将其添加到类/小部件中

当应用程序重新初始化自动创建的两个类属性
ObjectProperty
键入方法
rolldice()
,并指定默认值
None
时,链接被中断

解决方案
  • 引用
    TextInput
    对象的
    text
    属性,并将字符串转换为整数,
    int(self.diceNumber.text)
    int(self.diceType.text)
  • range()
    函数添加到
    for
    循环中
  • 在类级别声明
    ObjectProperty
    (这是可选的)
片段-示例 例子 以下示例说明Kivy自动创建了
ObjectProperty
类型的两个类属性,
diceNumber
diceType

main.py
随机导入
从kivy.app导入应用程序
从kivy.uix.screenmanager导入屏幕
从kivy.lang导入生成器
生成器。加载\u字符串(“”)
:#动态类
颜色:0,0,0,1#黑色文本
文本大小:self.size
哈利格:“左”
valign:“中间”
:
骰子号码:骰子号码
骰子类型:骰子类型
在以下情况之前:
颜色:
rgba:1,1,1,1#白色
矩形:
大小:self.size
pos:self.pos
盒子布局:
方向:“垂直”
网格布局:
科尔斯:2
行\强制\默认值:True
行\默认\高度:40
自定义标签:
文字:“您希望您的骰子有多少面(6代表D6,20代表D20等)?”
文本输入:
身份证号码
大小提示:无
宽度:100
自定义标签:
文字:“你想掷多少骰子?”
文本输入:
id:diceType
大小提示:无
宽度:100
按钮:
id:RollDice
文字:“掷骰子”
pos_提示:{“top”:0.3,“x”:0}
尺寸提示:0.4,0.2
背景颜色:0,0,0,0.1
颜色:0,0,0,1
发布时:
root.rolldice()
""")
分级辊(筛):
def rolldice(自我):
总数=0
打印(F“{self.diceNumber.text},D{self.diceType.text}”)
对于范围内的x(int(self.diceNumber.text)):
#x=x+1
ActualDie=random.randint(1,int(self.diceType.text))
总计+=实际值
打印(总计)
类TestApp(应用程序):
def生成(自):
回程滚筒()
如果名称=“\uuuuu main\uuuuuuuu”:
TestApp().run()
Problem-ObjectProperty@method-level 参考您提供的原始代码,即在方法级别声明的
ObjectProperty

根本原因 原因是,当您将
TextInput
小部件链接到kv文件中的属性时,Kivy将在关联的类/小部件中查找这些属性。如果类/小部件没有具有给定名称的属性,将自动创建
ObjectProperty
,并将其添加到类/小部件中

当应用程序重新初始化自动创建的两个类属性
ObjectProperty
键入方法
rolldice()
,并指定默认值
None
时,链接被中断

解决方案
  • 引用
    TextInput
    对象的
    text
    属性,并将字符串转换为整数,
    int(self.diceNumber.text)
    int(self.diceType.text)
  • range()
    函数添加到
    for
    循环中
  • 在类级别声明
    ObjectProperty
    (这是可选的)
片段-示例 例子 以下示例说明Kivy自动创建了
ObjectProperty
类型的两个类属性,
diceNumber
diceType

main.py
随机导入
从kivy.app导入应用程序
从kivy.uix.screenmanager导入屏幕
从kivy.lang导入生成器
生成器。加载\u字符串(“”)
:#动态类
颜色:0,0,0,1#黑色文本
文本大小:self.size
class DiceRoller(Screen):
    diceNumber = ObjectProperty(None)
    diceType = ObjectProperty(None)

    def rolldice(self):
        Total = 0    # initialize Total
        print(F"{self.diceNumber.text}, D{self.diceType.text}")

        for x in range(int(self.diceNumber.text)):

            ActualDie = random.randint(1, int(self.diceType.text))
            Total += ActualDie

        print(Total)
import random
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder

Builder.load_string("""
<CustomLabel@Label>:    # dynamic class
    color: 0, 0, 0,1    # black color text
    text_size: self.size
    halign: 'left'
    valign: 'middle'

<DiceRoller>:
    diceNumber: diceNumber
    diceType: diceType

    canvas.before:
        Color:
            rgba: 1, 1, 1, 1    # white
        Rectangle:
            size: self.size
            pos: self.pos

    BoxLayout:
        orientation: 'vertical'

        GridLayout:
            cols: 2
            row_force_default: True
            row_default_height: 40

            CustomLabel:
                text: 'How many sides do you want your dice to have (6 for D6, 20 for D20, etc)?'
            TextInput:
                id: diceNumber
                size_hint_x: None
                width: 100

            CustomLabel:
                text: 'How many dice do you want to roll?'
            TextInput:
                id: diceType
                size_hint_x: None
                width: 100

        Button:
            id: RollDice
            text: "Roll dice"
            pos_hint: {"top":0.3,"x":0}
            size_hint: 0.4, 0.2
            background_color: 0,0,0,0.1
            color: 0,0,0,1
            on_release:
                root.rolldice()
""")


class DiceRoller(Screen):

    def rolldice(self):
        Total = 0
        print(F"{self.diceNumber.text}, D{self.diceType.text}")

        for x in range(int(self.diceNumber.text)):
            # x = x + 1

            ActualDie = random.randint(1, int(self.diceType.text))
            Total += ActualDie

        print(Total)


class TestApp(App):

    def build(self):
        return DiceRoller()


if __name__ == "__main__":
    TestApp().run()