如何将kivy中的下拉小部件与python类一起使用
所以,我认为至少有两种方法可以在这个页面上设置一个下拉菜单,但这两种方法都不能工作。我对kivy和编程一般来说都是新手,但我已经阅读了文档,似乎我根本不懂 我创建了以下示例:如何将kivy中的下拉小部件与python类一起使用,python,class,drop-down-menu,kivy,query-by-example,Python,Class,Drop Down Menu,Kivy,Query By Example,所以,我认为至少有两种方法可以在这个页面上设置一个下拉菜单,但这两种方法都不能工作。我对kivy和编程一般来说都是新手,但我已经阅读了文档,似乎我根本不懂 我创建了以下示例: import kivy kivy.require('1.7.2') # replace with your current kivy version ! from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen fr
import kivy
kivy.require('1.7.2') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
class CustomDropDown(DropDown):
pass
class HomeScreen(Screen):
translateInput = ObjectProperty(None)
translateButton = ObjectProperty(None)
translateLabel = ObjectProperty(None)
top_layout = ObjectProperty(None)
dd_btn = ObjectProperty(None)
drop_down = CustomDropDown()
#notes_dropdown = ObjectProperty(None)
dropdown = DropDown()
notes = ['Features', 'Suggestions', 'Abreviations', 'Miscellaneous']
for note in notes:
# when adding widgets, we need to specify the height manually (disabling
# the size_hint_y) so the dropdown can calculate the area it needs.
btn = Button(text='%r' % note, size_hint_y=None, height=30)
# for each button, attach a callback that will call the select() method
# on the dropdown. We'll pass the text of the button as the data of the
# selection.
btn.bind(on_release=lambda btn: dropdown.select(btn.text))
# then add the button inside the dropdown
dropdown.add_widget(btn)
# create a big main button
mainbutton = Button(text='Usage Notes 2', size_hint=(1, 1))
# show the dropdown menu when the main button is released
# note: all the bind() calls pass the instance of the caller (here, the
# mainbutton instance) as the first argument of the callback (here,
# dropdown.open.).
mainbutton.bind(on_release=dropdown.open)
#dd_btn.bind(on_release=dropdown.open)
# one last thing, listen for the selection in the dropdown list and
# assign the data to the button text.
dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x))
#dropdown.bind(on_select=lambda instance, x: setattr(dd_btn, 'text', x))
#top_layout.add_widget(mainbutton)
class dropdApp(App):
def build(self):
return HomeScreen()
if __name__ == '__main__':
dropdApp().run()
这是相应的.kv文件:
#:kivy 1.7.2
<CustomDropDown>:
Button:
text: 'My first Item'
size_hint_y: None
height: 44
on_release: root.select('item1')
Label:
text: 'Unselectable item'
size_hint_y: None
height: 44
Button:
text: 'My second Item'
size_hint_y: None
height: 44
on_release: root.select('item2')
<HomeScreen>:
id: home_screen
translateInput: translateInputID
translateButton: translateButtonID
translateLabel: labelID
top_layout: topLayoutID
#notes_dropdown: notesDropDownID
dd_btn: btn_ddID
orientation: 'vertical'
FloatLayout:
size_hint: 1, .95
TextInput:
id: translateInputID
text: 'cove'
#text: 'ﻰﺸَﻣ'
font_name: "data/fonts/DejaVuSans.ttf"
background_color: 1, 1, 1, 1
size_hint: .75, .1
multiline: False
pos_hint: {'x': .125, 'y': .45}
text_size: self.size
valign: 'middle'
halign: 'center'
padding: 5
Button:
id: translateButtonID
text: 'Translate'
pos_hint: {'x': .35, 'y': .35}
size_hint: .3, .08
valign: 'middle'
halign: 'center'
text_size: self.size
on_release: root.translateButtonPressed()
#on_press: root.manager.current = 'resultsscreen'
Label:
id: labelID
text: 'Translator'
text_size: self.size
valign: 'middle'
halign: 'center'
pos_hint: {'x': .3, 'y': .75}
size_hint: .4, .2
#font_name: "simpo.ttf"
#font_name: "5thgradecursive.ttf"
#font_name: "AGA-Rasheeq-Regular.ttf"
font_name: "data/fonts/DejaVuSans.ttf"
font_size: 50
BoxLayout:
id: topLayoutID
#cols: 2
size_hint: 1, .05
pos_hint: {'x': 0, 'y': .95}
Button:
#id: notesDropDownID
id: btn_ddID
text: 'Usage Notes'
on_release: root.drop_down.open
Button:
text: 'About'
它在python和kivy方面都给了我一个句柄来操作它,但是当您运行它并单击“用法说明”时,您可能会注意到,什么都没有发生
AttributeError: 'kivy.properties.ObjectProperty' object has no attribute 'add_widget'
我意识到这是我设定的
top_layout = ObjectProperty(None)
但这正是kivy建议对许多小部件所做的,我对许多其他小部件所做的都没有这个错误\uuuu init\uuu
方法中。下面粘贴的代码显示了执行此操作所需的简单更改。您还需要将drop\u down
更改为self.drop\u down
,以便设置class属性,而不仅仅是生成局部变量
有时您确实希望在类变量处创建变量,该变量可用于类的所有实例。Kivy属性就是一个例子,它们有特殊的行为来控制它们在实际类实例中的行为。尽管如此,这是一个例外,而不是您希望对大多数代码执行的操作
实际上,我不完全确定代码失败的细节(不确定执行顺序/时间),但最终代码没有正确运行,小部件也没有正确初始化。如果遵循正常的\uuuuu init\uuuu
过程,这一切都很好
第二个错误是您的kv文件在发布时有:root.drop\u down.open
。问题是kv冒号右边的所有内容都是纯python,在本例中,您不调用该函数,只需声明其名称,因此不会发生任何事情。您需要将其替换为root.drop\u down.open(self)
,以获得正确的行为,因为open方法需要一个小部件作为参数
第二个下拉菜单也是在kivy文档之后用python创建的。我认为它会在应用程序顶部创建第三个按钮,标题为“用法说明2”。我只是在尝试添加时出错。现在,行(我的文件中有53行):
这是代码在类级别而不是在\uuuu init\uuu
方法中错误的另一个症状。问题是top_layout是一个ObjectProperty,在kv类中只显示为普通对象,因为该属性在类实例中管理其接口的特殊方式。当代码处于类级别时,它看不到特殊接口,因为它不是从类实例运行的(这与导致所有其他问题的原因相同),所以它会抛出错误,因为它看到的是ObjectProperty,而不是它的内容
在如下更改代码的情况下,添加小部件可以正常工作,因为\uuuu init\uuuu
从类实例运行,并且可以像普通属性一样与属性交互
我做了以下更改,两个下拉列表似乎都正常工作:
import kivy
kivy.require('1.7.2') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
class CustomDropDown(DropDown):
for i in range(5):
print i
class HomeScreen(Screen):
translateInput = ObjectProperty(None)
translateButton = ObjectProperty(None)
translateLabel = ObjectProperty(None)
top_layout = ObjectProperty(None)
dd_btn = ObjectProperty(None)
def __init__(self, *args, **kwargs):
super(HomeScreen, self).__init__(*args, **kwargs)
self.drop_down = CustomDropDown()
#notes_dropdown = ObjectProperty(None)
dropdown = DropDown()
notes = ['Features', 'Suggestions', 'Abreviations', 'Miscellaneous']
for note in notes:
# when adding widgets, we need to specify the height manually (disabling
# the size_hint_y) so the dropdown can calculate the area it needs.
btn = Button(text='%r' % note, size_hint_y=None, height=30)
# for each button, attach a callback that will call the select() method
# on the dropdown. We'll pass the text of the button as the data of the
# selection.
btn.bind(on_release=lambda btn: dropdown.select(btn.text))
# then add the button inside the dropdown
dropdown.add_widget(btn)
# create a big main button
mainbutton = Button(text='Usage Notes 2', size_hint=(1, 1))
print 'yay'
# show the dropdown menu when the main button is released
# note: all the bind() calls pass the instance of the caller (here, the
# mainbutton instance) as the first argument of the callback (here,
# dropdown.open.).
mainbutton.bind(on_release=dropdown.open)
#dd_btn.bind(on_release=dropdown.open)
# one last thing, listen for the selection in the dropdown list and
# assign the data to the button text.
dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x))
#dropdown.bind(on_select=lambda instance, x: setattr(dd_btn, 'text', x))
self.top_layout.add_widget(mainbutton)
class dropdApp(App):
def build(self):
return HomeScreen()
if __name__ == '__main__':
dropdApp().run()
千伏:
:
按钮:
文本:“我的第一项”
尺寸提示:无
身高:44
发布时:root.select('item1')
标签:
文本:“不可选择项”
尺寸提示:无
身高:44
按钮:
文本:“我的第二项”
尺寸提示:无
身高:44
发布时:root.select('item2')
:
id:主屏幕
translateInput:translateInputID
translateButton:translateButtonID
翻译标签:labelID
top_布局:topLayoutID
#notes_下拉列表:notesDropDownID
dd_btn:btn_ddID
方向:“垂直”
浮动布局:
尺寸提示:1.95
文本输入:
id:translateInputID
文字:“海湾”
#正文:'ﻰﺸَﻣ'
字体名称:“data/fonts/DejaVuSans.ttf”
背景颜色:1,1,1,1
大小提示:.75,.1
多行:False
位置提示:{'x':.125,'y':.45}
文本大小:self.size
valign:“中间”
哈利恩:“中心”
填充:5
按钮:
id:translateButtonID
文本:“翻译”
位置提示:{'x':.35,'y':.35}
大小提示:.3,.08
valign:“中间”
哈利恩:“中心”
文本大小:self.size
发布时:root.translateButtonPressed()
#按:root.manager.current='resultsscreen'
标签:
id:labelID
文本:“译者”
文本大小:self.size
valign:“中间”
哈利恩:“中心”
位置提示:{'x':.3,'y':.75}
大小提示:.4,.2
#字体名称:“simpo.ttf”
#字体名称:“5thgrade草书.ttf”
#字体名称:“AGA Rasheeq Regular.ttf”
字体名称:“data/fonts/DejaVuSans.ttf”
字体大小:50
top_layout = ObjectProperty(None)
import kivy
kivy.require('1.7.2') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
class CustomDropDown(DropDown):
for i in range(5):
print i
class HomeScreen(Screen):
translateInput = ObjectProperty(None)
translateButton = ObjectProperty(None)
translateLabel = ObjectProperty(None)
top_layout = ObjectProperty(None)
dd_btn = ObjectProperty(None)
def __init__(self, *args, **kwargs):
super(HomeScreen, self).__init__(*args, **kwargs)
self.drop_down = CustomDropDown()
#notes_dropdown = ObjectProperty(None)
dropdown = DropDown()
notes = ['Features', 'Suggestions', 'Abreviations', 'Miscellaneous']
for note in notes:
# when adding widgets, we need to specify the height manually (disabling
# the size_hint_y) so the dropdown can calculate the area it needs.
btn = Button(text='%r' % note, size_hint_y=None, height=30)
# for each button, attach a callback that will call the select() method
# on the dropdown. We'll pass the text of the button as the data of the
# selection.
btn.bind(on_release=lambda btn: dropdown.select(btn.text))
# then add the button inside the dropdown
dropdown.add_widget(btn)
# create a big main button
mainbutton = Button(text='Usage Notes 2', size_hint=(1, 1))
print 'yay'
# show the dropdown menu when the main button is released
# note: all the bind() calls pass the instance of the caller (here, the
# mainbutton instance) as the first argument of the callback (here,
# dropdown.open.).
mainbutton.bind(on_release=dropdown.open)
#dd_btn.bind(on_release=dropdown.open)
# one last thing, listen for the selection in the dropdown list and
# assign the data to the button text.
dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x))
#dropdown.bind(on_select=lambda instance, x: setattr(dd_btn, 'text', x))
self.top_layout.add_widget(mainbutton)
class dropdApp(App):
def build(self):
return HomeScreen()
if __name__ == '__main__':
dropdApp().run()
<CustomDropDown>:
Button:
text: 'My first Item'
size_hint_y: None
height: 44
on_release: root.select('item1')
Label:
text: 'Unselectable item'
size_hint_y: None
height: 44
Button:
text: 'My second Item'
size_hint_y: None
height: 44
on_release: root.select('item2')
<HomeScreen>:
id: home_screen
translateInput: translateInputID
translateButton: translateButtonID
translateLabel: labelID
top_layout: topLayoutID
#notes_dropdown: notesDropDownID
dd_btn: btn_ddID
orientation: 'vertical'
FloatLayout:
size_hint: 1, .95
TextInput:
id: translateInputID
text: 'cove'
#text: 'ﻰﺸَﻣ'
font_name: "data/fonts/DejaVuSans.ttf"
background_color: 1, 1, 1, 1
size_hint: .75, .1
multiline: False
pos_hint: {'x': .125, 'y': .45}
text_size: self.size
valign: 'middle'
halign: 'center'
padding: 5
Button:
id: translateButtonID
text: 'Translate'
pos_hint: {'x': .35, 'y': .35}
size_hint: .3, .08
valign: 'middle'
halign: 'center'
text_size: self.size
on_release: root.translateButtonPressed()
#on_press: root.manager.current = 'resultsscreen'
Label:
id: labelID
text: 'Translator'
text_size: self.size
valign: 'middle'
halign: 'center'
pos_hint: {'x': .3, 'y': .75}
size_hint: .4, .2
#font_name: "simpo.ttf"
#font_name: "5thgradecursive.ttf"
#font_name: "AGA-Rasheeq-Regular.ttf"
font_name: "data/fonts/DejaVuSans.ttf"
font_size: 50
BoxLayout:
id: topLayoutID
#cols: 2
size_hint: 1, .05
pos_hint: {'x': 0, 'y': .95}
Button:
#id: notesDropDownID
id: btn_ddID
text: 'Usage Notes'
on_release: root.drop_down.open(self)
Button:
text: 'About'
class DropBut(Button):
def __init__(self, **kwargs):
super(DropBut, self).__init__(**kwargs)
self.drop_list = None
self.drop_list = DropDown()
types = ['Item1', 'Item2', 'Item3', 'Item4', 'Item5', 'Item6']
for i in types:
btn = Button(text=i, size_hint_y=None, height=50)
btn.bind(on_release=lambda btn: self.drop_list.select(btn.text))
self.drop_list.add_widget(btn)
self.bind(on_release=self.drop_list.open)
self.drop_list.bind(on_select=lambda instance, x: setattr(self, 'text', x))