我正在使用kivy和python为我的大学做一个项目。我想做一个主屏幕,您可以在其中选择一些字段,然后下一个屏幕将取决于您在主屏幕中选择的字段。用kv语言做动态对我来说很难,因为我对kivy的编程知之甚少,所以我决定像python编程那样做,但它不起作用。这里有你的程序代码:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
Builder.load_string('''
<Root>:
MainScreen:
name: 'main'
AnotherScreen:
name: 'another'
<MainScreen>:
GridLayout:
cols: 2
Label:
text: "Select Subjects"
font_size: 15
Label:
text: " "
CheckBox:
on_active:root.ping('ch1')
Label:
text: "Termotecnia"
CheckBox:
on_active:root.ping('ch2')
Label:
text: "Control"
CheckBox:
on_active:root.ping('ch3')
Label:
text: "Termotcnia"
CheckBox:
on_active:root.ping('ch4')
Label:
text: "Control"
Button:
text: "Exit"
background_color: .7, .7, 6, 1
on_release:root.parent.current='another'
Button:
text: "Run"
font_size: 24
background_color: .7, .7, 1, 1
on_release: root.parent.current='another'
''')
class MainScreen(Screen):
def __init__(self, **kw):
super(MainScreen, self).__init__(**kw)
self.a = App.get_running_app()
self.e={}
def ping(self,n):
if self.a.big_dict[n]=='False':
self.a.big_dict[n]='True'
else:
self.a.big_dict[n]='False'
print self.a.big_dict
self.e=self.a.big_dict
class AnotherScreen(GridLayout):
def __init__(self, **kw):
super(AnotherScreen, self).__init__(**kw)
t=[]
self.i=MainScreen()
self.cols=2
self.add_widget(Button(text='Assignatura',background_color=[0,1,1,1]))
self.add_widget(Button(background_color=[0,1,1,1],text='Escriu Grup'))
for k in self.i.e:
if self.i.e[k]=='True':
self.add_widget(Label(text=k))
self.k=TextInput(multiline=False)
t.append(self.k.text)
self.add_widget(self.k)
else:
pass
b1=Button(text='Exit',background_color=[0,1,0,1])
self.add_widget(b1)
b2=Button(text='Run',background_color=[0,1,0,1])
self.add_widget(b2)
b1.bind(on_press=exit)
class Root(ScreenManager):
pass
class SimpleKivy(App):
big_dict={'ch1':'False','ch2':'False','ch3':'False','ch4':'False'}
def build(self):
return Root()
SimpleKivy().run()
此代码不起作用,因为ScreenManager
仅适用于Screen
,而不适用于GridLayout
(第一个问题)。 big_dict
保存复选框的数据,但是当我尝试导入到另一个类时,它不起作用(另一个问题)。如果有人知道这些问题的答案,那将非常有帮助,因为我知道如何处理例如总是有13个字段,但我想做预选,因为字段太多(在这个程序中只有4个字段,但有14个字段)。
答案 0 :(得分:0)
从哪里开始......
首先,让我们看一下SimpleKivy
。您可能希望将big_dict
设为DictProperty
,而不是使用类属性:
class SimpleKivy(App):
big_dict = DictProperty({'ch1':False,'ch2':False,'ch3':False,'ch4':False})
我也将价值观改为布尔值,因为以后会更有用。
然后,我们将AnotherScreen
的另一条规则添加到kv字符串中:
<AnotherScreen>:
GridLayout:
id: container
cols: 2
这样,我们可以通过id
来引用实际布局。
我们还更改了ping
:
def ping(self, n, value):
self.a.big_dict[n] = value
然后我们还将CheckBox
字符串中的kv
es更改为
CheckBox:
on_active:root.ping('ch1', self.active)
复选框的状态将直接传输到app实例中的字典。 (或者,如果您不需要ping
来处理其他事情,可以将其简化为on_active: app.big_dict['ch3'] = self.active
)
最后,AnotherScreen
的定义:
class AnotherScreen(Screen):
def on_pre_enter(self, *args):
t=[]
a = App.get_running_app()
self.ids.container.add_widget(Button(text='Assignatura',background_color=[0,1,1,1]))
self.ids.container.add_widget(Button(background_color=[0,1,1,1],text='Escriu Grup'))
for k,v in a.big_dict.iteritems():
if v:
self.ids.container.add_widget(Label(text=k))
self.k=TextInput(multiline=False)
t.append(self.k.text)
self.ids.container.add_widget(self.k)
b1=Button(text='Exit',background_color=[0,1,0,1])
self.ids.container.add_widget(b1)
b2=Button(text='Run',background_color=[0,1,0,1])
self.ids.container.add_widget(b2)
b1.bind(on_press=exit)
在输入屏幕之前调用它,将直接从应用程序实例获取字典(因此无需引用MainScreen
),并迭代所述字典。