我不知道那么多python,所以我不知道这个问题是不是更多kivy还是python。我想在点击/按下时调用父母的方法。但我无法访问根对象(AttributeError: 'IssueButton' object has no attribute 'root'
)或我之前定义的全局变量(NameError: name 'global_screen_manager' is not defined
)
我正在使用ScreenManager
来切换屏幕,而我正在使用ListView
和ListAdapter
创建这些按钮,我想称之为我正在谈论的这种方法。我没有得到的另一个有趣的事情就是这个按钮上面有几个父母,就像GridLayout
一样。
如何在py文件的底部为此IssueButton
定义根?
还有另一种从on-detail_press
调用方法IssueScreen
的好方法吗?
是否可以使用全局ScreenManager
或是否有一种传递引用的首选方法?
提前致谢!
这是我的代码:github.com/timokramer/repodigger
py:
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.listview import ListItemButton
from kivy.properties import ObjectProperty, ListProperty
from kivy.network.urlrequest import UrlRequest
import re
class RepodiggerApp(App):
def build(self):
root = Manager()
global global_screen_manager
global_screen_manager = root
return root
class Manager(ScreenManager):
login_screen = ObjectProperty(None)
issue_screen = ObjectProperty(None)
detail_screen = ObjectProperty(None)
burndown_screen = ObjectProperty(None)
class DetailScreen(Screen):
def __init__(self, **kwargs):
super(DetailScreen, self).__init__(**kwargs)
def populate_details(self):
pass
class BurndownScreen(Screen):
def __init__(self, **kwargs):
super(BurndownScreen, self).__init__(**kwargs)
class LoginScreen(Screen):
def get_input(self, text_input):
if text_input != "":
self.parse_input(text_input)
def parse_input(self, text_input):
if re.search(".[/].", text_input):
self.make_request(text_input)
else:
print("not a valid repo!")
def make_request(self, text_input):
headers = {'User-Agent': 'timokramer/repodigger'}
req = UrlRequest(
'https://api.github.com/repos/' + text_input + '/issues',
on_success=self.parse_request,
on_failure=self.parse_failure,
on_error=self.parse_error,
req_headers=headers,
debug=True
)
req.wait()
if req.is_finished:
print("Request Finished")
def parse_request(self, req, results):
print('Succeeded requesting Github Issues')
global_screen_manager.current = 'Issue Screen'
global_screen_manager.get_screen('Issue Screen').build_issue_widgets(results)
def parse_failure(self, req, result):
print('There was a problem: "', result['message'], '"')
def parse_error(self, req, error):
print('There was an error: ', error)
class IssueScreen(Screen):
my_item_strings = ListProperty([])
def __init__(self, **kwargs):
kwargs['cols'] = 1
super(IssueScreen, self).__init__(**kwargs)
def build_issue_widgets(self, issues):
for issue in issues:
if issue['state'] == 'open':
self.my_item_strings.append(issue['title'])
self.issues_list.item_strings = self.my_item_strings
self.issues_list.adapter.data.clear()
self.issues_list.adapter.data.extend(self.my_item_strings)
self.issues_list._trigger_reset_populate()
def on_burndown_press(self):
global_screen_manager.current = 'Burndown Screen'
def on_change_press(self):
global_screen_manager.current = 'Login Screen'
def on_detail_press(self):
global_screen_manager.current = 'Detail Screen'
global_screen_manager.get_screen('Detail Screen').populate_details()
class IssueButton(ListItemButton):
def on_detail_press(self):
print(self.parent)
print(self.parent.parent)
print(self.parent.parent.parent)
print(self.parent.parent.parent.parent)
print(self.parent.parent.parent.parent.parent)
self.parent.parent.parent.parent.parent.on_detail_press()
if __name__ == '__main__':
RepodiggerApp().run()
kv:
#: import Repodigger Repodigger
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
<Manager>:
id: screen_manager
login_screen: login_screen
issue_screen: issue_screen
detail_screen: detail_screen
burndown_screen: burndown_screen
canvas.before:
Color:
rgba: .1, .1, .1, 1
Rectangle:
pos: self.pos
size: self.size
LoginScreen:
id: login_screen
name: 'Login Screen'
manager: screen_manager
IssueScreen:
id: issue_screen
name: 'Issue Screen'
manager: screen_manager
DetailScreen:
id: detail_screen
name: 'Detail Screen'
manager: screen_manager
BurndownScreen:
id: burndown_screen
name: 'Burndown Screen'
manager: screen_manager
<BurndownScreen>:
BoxLayout:
id: burndown_screen
Button:
text: 'BURNDOWN!'
<IssueScreen>
issues_list: issues_list
BoxLayout:
size_hint: 1, 1
orientation: 'vertical'
ListView:
id: issues_list
size_hint: 1, .8
adapter:
ListAdapter(data=[], cls=Repodigger.IssueButton)
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .05
Button:
size_hint: .2, 1
text: "change Repository"
on_press: root.on_change_press()
Button:
size_hint: .2, 1
text: "show Burndown"
on_press: root.on_burndown_press()
<IssueButton>:
on_press: self.on_detail_press()
<DetailScreen>:
BoxLayout:
id: detail_screen
orientation: 'vertical'
Button:
text: "Detail View"
<LoginScreen>:
BoxLayout:
id: login_screen
size_hint: .7, .1
pos_hint: {'center_x': .5, 'center_y': .3}
rows:1
Label:
text: "Enter Github-Repo"
text_size: self.width-10, self.height-10
valign: 'middle'
halign: 'center'
size_hint_x: .3
TextInput:
id: text_input
on_text_validate: root.get_input(self.text)
text: ""
hint_text: "eg. timokramer/repodigger"
text_size: self.width-10, self.height-10
valign: 'middle'
halign: 'center'
padding_y: ( self.height - self.line_height ) / 2
size_hint_x: .5
multiline: False
Button:
id: ok_button
on_press: root.get_input(text_input.text)
text: "OK"
text_size: self.width-20, self.height-20
valign: 'middle'
halign: 'center'
size_hint_x: .2