Kivy Python - 如何在没有root的情况下访问父对象

时间:2015-06-19 18:49:58

标签: python kivy

我不知道那么多python,所以我不知道这个问题是不是更多kivy还是python。我想在点击/按下时调用父母的方法。但我无法访问根对象(AttributeError: 'IssueButton' object has no attribute 'root')或我之前定义的全局变量(NameError: name 'global_screen_manager' is not defined

我正在使用ScreenManager来切换屏幕,而我正在使用ListViewListAdapter创建这些按钮,我想称之为我正在谈论的这种方法。我没有得到的另一个有趣的事情就是这个按钮上面有几个父母,就像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

0 个答案:

没有答案