【问题标题】:Kivy - Binding a Label's Text to a Variable in Another ClassKivy - 将标签的文本绑定到另一个类中的变量
【发布时间】:2016-03-27 06:30:16
【问题描述】:

我试图在“scripts/events.py”中的事件类中的变量“current_text”时更新“EventWindow”中的标签文本。我意识到答案可能在于将“current_text”绑定到“ct”,但这只会导致“AttributeError:class Event has no attribute ‘bind’”。如果我用这个解决方案找错了树,我会很容易接受另一种方法。

以下是相关代码sn-ps,但完整项目可在:https://github.com/DinkWerks

main.py

from kivy.properties import ObjectProperty, StringProperty
from kivy.app import App
# Utility Imports
import yaml
# Game Imports
from scripts.events import Event

# File Loads
loc_file = file('data/location.yml')
loc_dat = yaml.load(loc_file)

# Bind Classes
event = Event()

class EventWindow(BoxLayout):
    ct = StringProperty('')

    def __init__(self, **kwargs):
        super(EventWindow, self).__init__(**kwargs)
        self.ct = event.current_text
        # Error occurs below. Comment out too see semi-functional app.
        Event.bind(current_text=self.setter('ct'))

脚本/事件.py

from kivy.properties import StringProperty
...
from player import Player
from enemy import Enemy


class Event(Player):
    open_events = file('data/event.yml', 'r')
    event_file = yaml.load(open_events)
    current_text = StringProperty('1234')

    def __init__(self):
        Player.__init__(self)
        self.events = Event.event_file
        self.selection = ''
        self.current_text = '1234'

def event_name(self):
    ...

def event_selector(self, eid):
    ...

def parse(self):
    driver = 1
    variables = ('Name', 'Is_Person', 'Level', 'Gold')
    poss_commands = ("[Next Slide]", "[Query]", "[Terminate]", "[Combat]")

    while driver >= 0:
        text = self.events[self.selection][driver]
        lexer = shlex(text)
        lexer.quotes = '/'

        output = ''
        command = ''
        for token in lexer:
            if token in variables:
                output += str(eval('Player.' + token))
            elif token.replace('/', '') in poss_commands:
                command += token.replace('/', '')
            else:
                output += token.replace('/', '')
        self.current_text = output
        driver += self.controller(command)
    self.modifier()

def modifier(self):
    ...

def controller(self, cmd):
    ...

text.kv

<EventWindow>:
    BoxLayout:
        pos: 100,100
        size_hint: .4,.7
        orientation: 'vertical'
        Image:
            source: 'maps/map.jpg'
            pos: self.pos
            size: self.size
        ScrollView:
            canvas.before:
                Color:
                    rgba: [.2,.2,.2,.8]
                Rectangle:
                    size: self.size
                    pos: self.pos
            Label:
                id: text_area
                text: root.ct
                padding: 15,10
                text_size: self.width, None
                size_hint_y: None
                height: self.texture_size[1]
<Foo>:
    id: bl
    popup: popup.__self__
    header: header
    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            ...
        FloatLayout:
            id: mapspace
            canvas:
                ...
            EventWindow:
                id: event
    Popup:
        ...

谢谢!

【问题讨论】:

  • Event 没有实现处理 kivy 使用的事件的方法和机制。尽量让它成为EventDispatcher 的子类,除非你的Player 类做了奇怪的事情,它应该可以工作。
  • 这非常有效,而且绝对有意义。如果您想重新提交,我很乐意将其注册为正确答案。

标签: python python-2.7 user-interface kivy


【解决方案1】:

在您的代码中,Event 派生自 Player,它本身就是一个 old style class。重要的是,两者都没有实现事件管理所需的方法(例如fbind;对于定义接口的存根类,请参阅Observable)。很可能将EventPlayer 设为EventDispatcher 的子类就足以创建并绑定到kivy 样式的事件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 2020-02-23
    • 2014-07-06
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    相关资源
    最近更新 更多