【问题标题】:How to access class instance initiated by the Kivy code?如何访问由 Kivy 代码发起的类实例?
【发布时间】:2020-10-14 23:12:09
【问题描述】:

我被困住了。我不知道如何访问在 Kivy 文件中启动的对象?

这是我的代码:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
import time
from kivy.uix.screenmanager import Screen, ScreenManager

import filestack

Builder.load_file("test.kv")

class LoginScreen(Screen):

    def create_file(self):
        filename = f"file_{time.strftime('%Y%m%d_%H%M%S')}.txt"
        with open(filename, 'w') as file:
            file.write("Some content")


class RootWidget(ScreenManager):
    pass

class MainApp(App):
    def build(self):
        return RootWidget()

class FileSharer:

    def __init__(self, filepath, api_key="abcdefg"):
        self.filepath = filepath
        self.api_key = api_key

    def share(self):
        client = filestack.Client(self.api_key)
        new_filelink = client.upload(filepath=self.filepath)
        return new_filelink.url

MainApp().run()

还有我的test.kv 文件:

<LoginScreen>:
    GridLayout:
        cols: 1
        padding: 10, 10
        spacing: 10, 10
        Button:
            text: 'Create File'
            size_hint_y: None
            height: '48dp'
            on_press: root.create_file()

<RootWidget>:
    LoginScreen:
        id: login_screen
        name: "login_screen"

这是程序产生的视觉效果:

创建文件按钮被按下时,Kivy文件调用LoginScreen.create_file()方法,并创建一个名称包含当前时间戳的文本文件(例如file_20200624_173229.txt)。

我希望能够从 Python 代码中访问该文件名。我想这样做的原因是我想使用 FileSharer 类将文件上传到云端。为此,我需要像 FileSharer(filepath=...) 一样初始化 FileSharer

我知道我可以通过使用os.listdir() 在磁盘中查找生成的文件来解决此问题,但我想以正确的方式执行此操作,即从LoginScreen 实例访问filename 的值.

【问题讨论】:

    标签: python class attributes kivy


    【解决方案1】:

    有几种方法可以做到这一点。这是一个。您可以在LoginScreen 中创建一个StringProperty 来包含创建的文件名:

    class LoginScreen(Screen):
        filename = StringProperty('')
    
        def create_file(self):
            self.filename = f"file_{time.strftime('%Y%m%d_%H%M%S')}.txt"
            with open(self.filename, 'w') as file:
                file.write("Some content")
    

    create_file() 方法将文件名保存到filename 属性中。

    然后您可以通过多种方式访问​​文件名,例如login_screen_instance.filename,或者利用它现在是Property 的事实,您可以在kv 中使用它:

    <RootWidget>:
        LoginScreen:
            id: login_screen
            name: "login_screen"
            on_filename: root.get_file(self.filename)
    

    并将get_file() 方法添加到RootWidget

    class RootWidget(ScreenManager):
        def get_file(self, filename):
            print('file is', filename)
    

    现在,每当create_file() 方法创建新文件时,都会调用get_file() 方法。

    【讨论】:

    • 感谢您的回答。尝试在我的代码中应用它,如果我尝试在我的 .py 文件中使用 login_screen_instance 变量,我会得到一个 NameError: name 'login_screen_instance' is not defined。我以为您的意思是 .py 文件中会有一个特殊的 login_screen_instance 变量,还是我弄错了?
    • 所以,我的线程的主要问题是如何访问 Kivy 代码创建的 LoginScreen 实例。
    • 由于访问LoginScreen 的实例有很多不同的方法,我提到login_screen_instance 的评论是如何使用LoginSceen 的实例访问filename 的一个示例。您可以使用App.get_running_app().root.ids.login_screen 访问LoginScreen
    • 成功了!你知道App.get_running_app().root.ids.login_screen到底是什么吗?是 LoginScreen 类本身还是该类的实例?当我做type(App.get_running_app().root.ids.login_screen) 时,我得到class 'kivy.weakproxy.WeakProxy。关于该 WeakProxy 类型的 Kivy 文档几乎没有给出任何解释。我们使用App.get_running_app().root.ids.login_screen 访问的确切信息是什么?
    • 访问由您的kv 文件创建的LoginScreen 实例。它使用WeakProxy,它只是对不计入垃圾回收的实例的引用。
    猜你喜欢
    • 2021-06-24
    • 2023-01-07
    • 1970-01-01
    • 2021-04-23
    • 2021-12-27
    • 1970-01-01
    • 2021-11-07
    • 2021-10-25
    • 2021-06-01
    相关资源
    最近更新 更多