Kivy:修改另一个单独类的子窗口小部件 [英] Kivy: Modifying a child widget of another separate class

查看:51
本文介绍了Kivy:修改另一个单独类的子窗口小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在研究kivy,以开始跨平台开发.我有一些python的经验(但很基础),现在想用kivy编写一个小游戏来入门.我可能不会完成此操作,但是我喜欢在学习过程中学习一些有趣的东西. 无论如何,我的应用程序"应该被分成两个单独的屏幕",最上面的一个仅用于显示内容,而所有交互式内容均由最下面的屏幕"控制.

现在,我想通过将其逐个字母地写到屏幕上,以老式的方式显示一些文本. 这工作正常,但由于某种原因,如果我从顶部屏幕调用"print_something"功能,则仅在屏幕上更新标签小部件,如果从底部屏幕调用它,则确实会调用该功能,但标签小部件不会在屏幕上更改. 难道我做错了什么?

以下是该代码的摘要版本:

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.clock import Clock

Builder.load_string('''
<MainUI>:
    orientation: 'vertical'
    # both these variables can be the same name and this doesn't lead to
    # an issue with uniqueness as the id is only accessible in kv.
<Screen1>:
    print_txt: print_txt
    layout: layout
    RelativeLayout:
        id: layout
        pos: 0, 400
        size: 480, 400
        Button:
            pos: 0, 200
            size_hint: (1, 0.2)
            text: "Test Print"
            on_press: root.print_something('TEST PRINT FROM SCREEN1')
        AnchorLayout:
            anchor_x: 'center'
            anchor_y: 'bottom'
            Label:
                id: print_txt
                padding_x: 10
                markup: True
                text_size: self.size
                halign: 'left'
                valign: 'top'
                size_hint: (1, 0.2)
                text: ""
<Screen2>:
    btn1: btn1
    RelativeLayout:
        pos: 0, 0
        size: 480, 400
        Button:
            id: btn1
            pos_hint: {'x': .15, 'center_y': .5}
            size_hint: (0.7, 0.5)
            text: "Test Print"
            on_press: root.print_text()
''')


class Screen1(Widget):
    print_txt = ObjectProperty(None)
    layout = ObjectProperty(None)
    def print_something(self, string):
        print 'Function called...'
        self.print_txt.text = ''
        counter = [0]
        string_len = len(string)
        def print_step(dt):
            if counter[0] == string_len:
                return False
            else:
                self.print_txt.text += string[counter[0]]
                counter[0] = counter[0] + 1
        Clock.schedule_interval(print_step, 2.0/60.0)
        print 'Function End..'

class Screen2(Widget):
    btn1 = ObjectProperty(None)

    def __init__(self):
        super(Screen2, self).__init__()

    def print_text(self):
        print 'Trying to print Text from Screen2 to Screen1'
        target = Screen1()
        target.print_something('TEST PRINT FROM SCREEN2')

class MainUI(Widget):
    def __init__(self):
        super(MainUI, self).__init__()
        self.screen1 = Screen1()
        self.add_widget(self.screen1)
        self.add_widget(Screen2())

class MainApp(App):

    def build(self):
        Window.size = (480, 800)
        return MainUI()

if __name__ == '__main__':
    MainApp().run()

解决方案

您的Screen2 print_text方法创建一个 new Screen1实例,该实例已修改但未显示在任何地方,因此您看不到任何变化.

您可以将呼叫更改为

on_press: root.parent.screen1.print_text()

...访问您实际要更新的Screen1实例的print_text函数.

im currently looking into kivy to start with crossplatform development. i have a bit of python experience (but basic) and now wanted to code a little game in kivy to get into. i probably wont finish this but i like learning stuff while doing it with something im intrested in. Anyway my "App" is supposed to be seperated in two seperate "screens" the top one is only used for displaying stuff and the all interactive stuff is controlled from the bottom "screen".

Now i want to display some text in old school way by getting it written letter by letter to the screen. This is working fine but for some reason the Label widget is only updated on screen if i call the "print_something" function from the top screen, if i call it from the bottom screen the function is indeed called but the Label widget wont change on screen. Am i doing something wrong?

Here is a stripped version of the code:

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.clock import Clock

Builder.load_string('''
<MainUI>:
    orientation: 'vertical'
    # both these variables can be the same name and this doesn't lead to
    # an issue with uniqueness as the id is only accessible in kv.
<Screen1>:
    print_txt: print_txt
    layout: layout
    RelativeLayout:
        id: layout
        pos: 0, 400
        size: 480, 400
        Button:
            pos: 0, 200
            size_hint: (1, 0.2)
            text: "Test Print"
            on_press: root.print_something('TEST PRINT FROM SCREEN1')
        AnchorLayout:
            anchor_x: 'center'
            anchor_y: 'bottom'
            Label:
                id: print_txt
                padding_x: 10
                markup: True
                text_size: self.size
                halign: 'left'
                valign: 'top'
                size_hint: (1, 0.2)
                text: ""
<Screen2>:
    btn1: btn1
    RelativeLayout:
        pos: 0, 0
        size: 480, 400
        Button:
            id: btn1
            pos_hint: {'x': .15, 'center_y': .5}
            size_hint: (0.7, 0.5)
            text: "Test Print"
            on_press: root.print_text()
''')


class Screen1(Widget):
    print_txt = ObjectProperty(None)
    layout = ObjectProperty(None)
    def print_something(self, string):
        print 'Function called...'
        self.print_txt.text = ''
        counter = [0]
        string_len = len(string)
        def print_step(dt):
            if counter[0] == string_len:
                return False
            else:
                self.print_txt.text += string[counter[0]]
                counter[0] = counter[0] + 1
        Clock.schedule_interval(print_step, 2.0/60.0)
        print 'Function End..'

class Screen2(Widget):
    btn1 = ObjectProperty(None)

    def __init__(self):
        super(Screen2, self).__init__()

    def print_text(self):
        print 'Trying to print Text from Screen2 to Screen1'
        target = Screen1()
        target.print_something('TEST PRINT FROM SCREEN2')

class MainUI(Widget):
    def __init__(self):
        super(MainUI, self).__init__()
        self.screen1 = Screen1()
        self.add_widget(self.screen1)
        self.add_widget(Screen2())

class MainApp(App):

    def build(self):
        Window.size = (480, 800)
        return MainUI()

if __name__ == '__main__':
    MainApp().run()

解决方案

Your Screen2 print_text method creates a new Screen1 instance, which is modified but not displayed anywhere so you don't see anything change.

You could change the call to instead something like

on_press: root.parent.screen1.print_text()

...to access the print_text function of the Screen1 instance that you actually want to update.

这篇关于Kivy:修改另一个单独类的子窗口小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆