如何访问由 Kivy 代码发起的类实例?
Posted
技术标签:
【中文标题】如何访问由 Kivy 代码发起的类实例?【英文标题】:How to access class instance initiated by the Kivy code? 【发布时间】: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
的值.
【问题讨论】:
【参考方案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
,它只是对不计入垃圾回收的实例的引用。以上是关于如何访问由 Kivy 代码发起的类实例?的主要内容,如果未能解决你的问题,请参考以下文章