我希望将.py模块中定义的应用程序的所有变量与main.py文件分开。然后我想在kivy文件中使用这些变量。
我尝试了以下代码,并进行了多种更改,并且始终会出现错误。该模块可以很好地用于定义例如不同的Fonts,但是当涉及properties(ObjectProperty)时,它将无法正常工作。
项目结构:
KivyFolder
模块(文件夹)
屏幕(文件夹)
screen1.kv
screen2.kv
main.py
代码:
main.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from os import listdir
from kivy.lang import Builder
kv_screens = './screens/'
for kv in listdir(kv_screens):
Builder.load_file(kv_screens+kv)
class Screen1(Screen):
pass
class Screen2(Screen):
pass
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file('main.kv')
class MainApp(App):
import modules.variables
def build(self):
return presentation
if __name__ == '__main__':
MainApp().run()
main.kv
#:kivy 1.10.1
ScreenManagement:
Screen1:
Screen2:
screen1.kv
#:kivy 1.10.1
<Screen1>:
name: 's1'
BoxLayout:
orientation: 'vertical'
Label:
text: 'Screen 1'
font_size: app.font_size_one
Button:
text: 'Go To Screen 2'
on_press:
root.manager.current = 's2'
screen2.kv
#:kivy 1.10.1
<Screen2>:
name: 's2'
BoxLayout:
orientation: 'vertical'
Label:
text: 'Screen 2'
font_size: '20dp'
Button:
text: 'Go To Screen 1'
on_press:
root.manager.current = 's1'
variables.py
from kivy.properties import ObjectProperty
font_size_one = ObjectProperty('40dp')
font_size_two = ObjectProperty('60dp')
现在这样做会产生此错误:
AttributeError:'NoneType'对象没有属性'bind'
我希望能够调用一个变量,因为它是从MainApp(App)导入的,因此'app.variable name应该读取它。
我也尝试过:
font_size: app.variables.font_size_one
和:
font_size: app.modules.variables.font_size_one
然后我尝试在导入其他所有模块之前导入模块,结果相同。
我还尝试将其放入类中,并在.kv中像这样调用该类:
variables.py
from kivy.properties import ObjectProperty
class FVArs():
font_size_one = ObjectProperty('40dp')
font_size_two = ObjectProperty('60dp')
screen1.kv
#:kivy 1.10.1
<Screen2>:
name: 's2'
BoxLayout:
orientation: 'vertical'
Label:
text: 'Screen 2'
font_size: FVars().font_size_two
Button:
text: 'Go To Screen 1'
on_press:
root.manager.current = 's1'
错误:
NameError:名称“ FVars”未定义
谢谢您的回答。
再见
编辑:由于以下答案适用于示例代码,但不适用于我的实际项目,因此我要添加相关的项目代码:
项目结构:
KivyFolder
模块(文件夹)
屏幕(文件夹)
Intro.kv
(以及其他屏幕作为单独的.kv文件
main.py
main.py
from kivy.app import App
from modules.global_variables import globalVariables
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.label import Label
from kivy.properties import StringProperty, NumericProperty, ObjectProperty, Property
from kivy.core.window import Window
background_color = (0.1, 0.1, 0.1, 1)
Window.clearcolor = background_color
from os import listdir
from kivy.lang import Builder
kv_screens = './screens/'
for kv in listdir(kv_screens):
Builder.load_file(kv_screens+kv)
kv_elements = './elements/'
for kv in listdir(kv_elements):
Builder.load_file(kv_elements+kv)
class IntroScreen(Screen):
user_name = StringProperty("Troll")
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file("main.kv")
class MainApp(App):
title_size = globalVariables.title_size
def build(self):
self.title = 'Kivy Omnia!'
return presentation
if __name__ == "__main__":
app = MainApp()
app.run()
global_variables.py
from kivy.properties import ObjectProperty
class globalVariables():
title_size = ObjectProperty('101sp')
main.kv
#:kivy 1.10.1
ScreenManagement:
IntroScreen:
intro.kv
#:kivy 1.10.1
<IntroScreen>:
name: "intro"
BoxLayout:
orientation: 'vertical'
Label:
text: "Hello " + root.user_name + "!"
font_size: app.title_size
错误:
kivy.lang.builder.BuilderException:解析器:文件 “ C:\ Users \ Ghost \ CodeProjects \ phyton \ kivyomnia \ screens \ Intro.kv”,行 10:... 8:标签: 9:文本:“ Hello” + root.user_name +“!”
10:font_size:app.title_size 11:font_name:“ Exo-B” 12:AnchorLayout:... BuilderException:解析器:文件“ C:\ Users \ Ghost \ CodeProjects \ phyton \ kivyomnia \ screens \ Intro.kv”,行 10:... 8:标签: 9:文本:“ Hello” + root.user_name +“!” 10:font_size:app.title_size 11:font_name:“ Exo-B” 12:AnchorLayout:... AttributeError:“ NoneType”对象没有属性“ bind”文件 “ C:\ Python37-32 \ lib \ site-packages \ kivy \ lang \ builder.py”,第249行,在 create_handler 返回eval(值,idmap),绑定列表文件“ C:\ Users \ Ghost \ CodeProjects \ phyton \ kivyomnia \ screens \ Intro.kv”,行 10,在 font_size:app.title_size文件“ C:\ Python37-32 \ lib \ site-packages \ kivy \ lang \ parser.py”,第75行,在 获取属性 对象。 getattribute ((自身,'_ ensure_app')()文件“ C:\ Python37-32 \ lib \ site-packages \ kivy \ lang \ parser.py”,第70行,在 _ensure_app app.bind(on_stop = lambda实例:
文件“ C:\ Python37-32 \ lib \ site-packages \ kivy \ lang \ builder.py”,行 615,在_apply_rule中 rctx ['ids'])文件“ C:\ Python37-32 \ lib \ site-packages \ kivy \ lang \ builder.py”,第254行,在 create_handler cause = tb)
因此,只要重新定位:
title_size = globalVariables.title_size
...在IntroScreen(屏幕)内,然后在Intro.kv内:
font_size: root.title_size
...有效。但是关键是要在所有屏幕上都提供所有全局变量。
另一个问题:
如果app.something得到主应用程序类内部的内容 然后root.something获取该文件的根类中的内容,然后如何从另一个非app或root的类中调用某些内容。如果这样的话。
答案 0 :(得分:0)
您可以使用此行导入FVars
类:
from modules.variables import FVars
然后在MainApp
类中,可以使用FVars
的类变量的数据创建一个类变量。
class MainApp(App):
f1 = FVars.font_size_one
然后您可以在您的kv文件中访问它:
font_size: app.f1
这是一些基本示例:
main.py
from kivy.app import App
from kivy.lang import Builder
from modules.variables import FVars
class Test(App):
f1 = FVars.font_size_one
def build(self):
return Builder.load_file("test.kv")
Test().run()
test.kv
BoxLayout:
Label:
text: "Hello"
font_size: app.f1
modules / variables.py
from kivy.properties import ObjectProperty
class FVars():
font_size_one = ObjectProperty('40dp')
font_size_two = ObjectProperty('60dp')
更新
为防止错误,您可以在build
方法内加载kv文件。
def build(self):
self.title = 'Kivy Omnia!'
kv_screens = './screens/'
for kv in listdir(kv_screens):
Builder.load_file(kv_screens+kv)
kv_elements = './elements/'
for kv in listdir(kv_elements):
Builder.load_file(kv_elements+kv)
presentation = Builder.load_file("main.kv")
return presentation
关于如何访问既不是app
也不是root
的类中的变量,有很多方法,您只需设置该小部件的id
属性即可。
这是一个基本示例:
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
class SecondClass(BoxLayout):
someNumber = 123 # Let's say we wanted to print the value of this variable when we press the button.
class FirstClass(BoxLayout):
pass
class TestApp(App):
def build(self):
return FirstClass()
TestApp().run()
test.kv
<SecondClass>:
<FirstClass>:
Button:
text: "Print the Numbah"
on_press: print(app.root.ids.secondclass.someNumber) # We can do something like this
SecondClass:
id: secondclass
我们还可以执行以下操作:
<SecondClass>:
<FirstClass>:
Button:
text: "Print the Numbah"
on_press: print(root.ids.secondclass.someNumber)
SecondClass:
id: secondclass
或者这个:
<SecondClass>:
<FirstClass>:
Button:
text: "Print the Numbah"
on_press: print(secondclass.someNumber)
SecondClass:
id: secondclass
甚至是这样:
<SecondClass>:
<FirstClass>:
second: secondclass
Button:
text: "Print the Numbah"
on_press: print(app.root.second.someNumber)
SecondClass:
id: secondclass
这:
<SecondClass>:
<FirstClass>:
second: secondclass
Button:
text: "Print the Numbah"
on_press: print(root.second.someNumber)
SecondClass:
id: secondclass