因此,当我按下ListView项时,我无法找到通过过程传递值的方法。以下示例是我想要发生的更简单的版本以及我的主要代码的设置方式。 目标是在KV文件中的哈希标记 on_release:上看到 ChangeScreen(self.index)。但问题是我不知道如何成功调用ChangeScreen。谢谢!
Kivy:
#: import main main
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
AppScreenManager:
DemoScreen1:
id: screen1
DemoScreen2:
id: screen2
<DemoScreen1>:
name: "demoscreen1"
BoxLayout:
orientation: "vertical"
ListView:
adapter:
ListAdapter(data=["Screen 1","Screen 2"], cls=main.ListButton)
<DemoScreen2>:
name: "demoscreen2"
orientation: "vertical"
BoxLayout:
orientation: "vertical"
Label:
id: labText
text: "Hello World"
<ListButton>:
height: self.texture_size[1]
on_release: ### HOW DO I CALL THE ChangeScreen FUNCTION HERE
的Python:
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty, ObjectProperty, ListProperty
from kivy.uix.listview import ListItemButton
class DemoScreen1(Screen):
def ChangeScreen(self, option):
if option == 0:
print("Screen1")
self.parent.ids.screen2.labelUpdater("Screen 1 was pressed")
else:
print("Screen2")
self.parent.ids.screen2.labelUpdater("Screen 2 was pressed")
self.parent.current = "demoscreen2"
class DemoScreen2(Screen):
labText = StringProperty()
def labelUpdater(self,newText):
self.ids.labText.text = newText
class ListButton(ListItemButton):
data = ListProperty()
class AppScreenManager(ScreenManager):
pass
class Tester(App):
pass
if __name__ == '__main__':
Tester().run()
答案 0 :(得分:1)
另一种解决方案:
...
<ListButton>:
height: self.texture_size[1]
on_release: self.parent.parent.parent.parent.parent.ChangeScreen(self.index)
...
但是只针对on_press
,on_release
这样的事件执行此操作,因为on_parent
永远不会为self.parent.parent.parent
执行此事件,因为他们在调用最后一个事件时没有父母
要获得解释,您必须知道的是ListView
是您的SUGAR.util = function () {
var additionalDetailsCache;
var additionalDetailsCalls;
var additionalDetailsRpcCall;
return{getAndRemove: function (el) {
if (YAHOO && YAHOO.util && YAHOO.util.Dom)
el = YAHOO.util.Dom.get(el);
else if (typeof (el) == "string")
el = document.getElementById(el);
if (el && el.parentNode)
el.parentNode.removeChild(el);
return el;
}, paramsToUrl: function (params) {
var parts = [];
for (var i in params) {
if (params.hasOwnProperty(i)) {
parts.push(encodeURIComponent(i) + '=' + encodeURIComponent(params[i]));
}
}
return parts.join("&") + "&";
}, globalEval: function (data) {
var rnotwhite = /\S/;
if (data && rnotwhite.test(data)) {
(window.execScript || function (data) {
window["eval"].call(window, data); //<====== THIS IS THE LINE MENTIONED IN THE WEB BROWSER'S CONSOLE
})(data);
}
我希望这会有所帮助
答案 1 :(得分:1)
我认为你应该这样做:
ChangeScreen
方法应移至ScreenManager
:它是a
管理屏幕更改的屏幕管理员。
更改选择的反应应放在ListAdapter
内:
list adapter - 是一个控制器,用于管理选择中发生的事情
on_selection_change
事件。
您可以使用与您相同的方式继承ListAdapter
ListItemButton
。
放置在kvfile中调用的回调是(恕我直言)坏主意:kvfile是一种视图,将回调留给cotrollers,例如ListAdapter
。再次,它可以继承ListAdapter
。
由于ListAdapter
使用ScreenManager
&#39; ChangeScreen
方法,因此适配器应该与屏幕一起使用(替代它可以像EL3PHANTEN建议的那样放置{{1}进入App,但它变成了一种全局变量。)
此处的重构代码包含上述所有建议:
<强> tester.kv 强>
ScreenManager
<强> main.py 强>
#: import main main
AppScreenManager:
DemoScreen1:
id: screen1
DemoScreen2:
id: screen2
<DemoScreen1>:
name: "demoscreen1"
BoxLayout:
orientation: "vertical"
ListView:
adapter:
main.MyListAdapter(
data=["Screen 1","Screen 2"],
cls=main.MyListButton,
scr=root.parent
)
<DemoScreen2>:
name: "demoscreen2"
orientation: "vertical"
BoxLayout:
orientation: "vertical"
Label:
id: labText
text: "Hello World"
<MyListButton>:
height: self.texture_size[1]
答案 2 :(得分:0)
请尝试将changeScreen
方法放在ListButton
课程中
然后将ScreenManager
作为App
类中的属性。你可以在kv中以app.sm
的形式访问它
然后,您可以将app.sm
传递给ChangeScreen
方法,以获取屏幕
以下是您修改过的示例:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.listview import ListItemButton
from kivy.lang import Builder
class DemoScreen2(Screen):
def labelUpdater(self,newText):
self.ids.labText.text = newText
class ListButton(ListItemButton):
data = ListProperty()
def ChangeScreen(self, option, sm):
if option == 0:
print("Screen1")
sm.ids.screen2.labelUpdater("Screen 1 was pressed")
else:
print("Screen2")
sm.ids.screen2.labelUpdater("Screen 2 was pressed")
sm.current = "demoscreen2"
class AppScreenManager(ScreenManager):
pass
KV = """
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
#: import Factory kivy.factory.Factory
<AppScreenManager>:
DemoScreen1:
id: screen1
DemoScreen2:
id: screen2
<DemoScreen1@Screen>:
name: "demoscreen1"
BoxLayout:
orientation: "vertical"
ListView:
adapter:
ListAdapter(data=["Screen 1","Screen 2"], cls=Factory.ListButton)
<DemoScreen2>:
name: "demoscreen2"
orientation: "vertical"
BoxLayout:
orientation: "vertical"
Button:
id: labText
text: "Hello World"
on_release:
app.sm.current = "demoscreen1"
<ListButton>:
height: self.texture_size[1]
on_release: root.ChangeScreen(self.index,app.sm)
"""
class Tester(App):
def build(self):
Builder.load_string(KV)
self.sm = AppScreenManager()
return self.sm
if __name__ == '__main__':
Tester().run()