<i id='wIu94'><tr id='wIu94'><dt id='wIu94'><q id='wIu94'><span id='wIu94'><b id='wIu94'><form id='wIu94'><ins id='wIu94'></ins><ul id='wIu94'></ul><sub id='wIu94'></sub></form><legend id='wIu94'></legend><bdo id='wIu94'><pre id='wIu94'><center id='wIu94'></center></pre></bdo></b><th id='wIu94'></th></span></q></dt></tr></i><div id='wIu94'><tfoot id='wIu94'></tfoot><dl id='wIu94'><fieldset id='wIu94'></fieldset></dl></div>
    1. <legend id='wIu94'><style id='wIu94'><dir id='wIu94'><q id='wIu94'></q></dir></style></legend>
      <tfoot id='wIu94'></tfoot>

      <small id='wIu94'></small><noframes id='wIu94'>

      • <bdo id='wIu94'></bdo><ul id='wIu94'></ul>

      为什么我无法访问 Screen.ids?

      时间:2023-10-10

      <small id='CxxeJ'></small><noframes id='CxxeJ'>

        <tfoot id='CxxeJ'></tfoot>

            <tbody id='CxxeJ'></tbody>
          <legend id='CxxeJ'><style id='CxxeJ'><dir id='CxxeJ'><q id='CxxeJ'></q></dir></style></legend>
          <i id='CxxeJ'><tr id='CxxeJ'><dt id='CxxeJ'><q id='CxxeJ'><span id='CxxeJ'><b id='CxxeJ'><form id='CxxeJ'><ins id='CxxeJ'></ins><ul id='CxxeJ'></ul><sub id='CxxeJ'></sub></form><legend id='CxxeJ'></legend><bdo id='CxxeJ'><pre id='CxxeJ'><center id='CxxeJ'></center></pre></bdo></b><th id='CxxeJ'></th></span></q></dt></tr></i><div id='CxxeJ'><tfoot id='CxxeJ'></tfoot><dl id='CxxeJ'><fieldset id='CxxeJ'></fieldset></dl></div>
          • <bdo id='CxxeJ'></bdo><ul id='CxxeJ'></ul>

              1. 本文介绍了为什么我无法访问 Screen.ids?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                更新:

                Ryan P 的回答提供了解决方案.但是,我采用了该解决方案并对其进行了一些更改,丢弃了所有不存在的数据正确初始化为 RootWidget 的 on_enter 方法屏幕.这效果很好.

                Ryan P's answer provided the solution. However, I took that solution and changed it up a bit, throwing all of the data that wasn't being properly initialised into the on_enter method of the RootWidget Screen. This has worked nicely.

                直到今天,我的 RootWidget 类都是 Widget 的子类,我可以毫无问题地访问它的 id 来获取grid"的值.然而,我只是改变了它是Screen的子类,现在它说由于某种原因ID是空的……Screen确实有一个ID和所有这些,但由于某种原因,它没有注册那个我在 kv 文件中为 id ''grid'' 分配了一个 GridLayout.谁能告诉我为什么?

                My RootWidget class was subclassing Widget until today, and I had no problem accessing it's ids to get the value of "grid". However, I just changed it to subclass Screen, and now it says the ids is empty for some reason... Screen does have an ids and all that, but for some reason, it isn't registering that I assigned a GridLayout to the id ''grid'' in the kv file. Can anyone tell me why?

                回溯:

                [INFO   ] [Logger      ] Record log in /home/yerman/.kivy/logs/kivy_14-11-13_201.txt
                [INFO   ] Kivy v1.9.0-dev
                [INFO   ] [Python      ] v2.7.6 (default, Mar 22 2014, 22:59:56) 
                [GCC 4.8.2]
                [INFO   ] [Factory     ] 172 symbols loaded
                [INFO   ] [Image       ] Providers: img_tex, img_dds, img_pygame, img_pil, img_gif (img_sdl2, img_ffpyplayer ignored)
                [INFO   ] [Window      ] Provider: pygame(['window_egl_rpi'] ignored)
                [WARNING] [WinPygame   ] Video: failed (multisamples=2)
                [WARNING] [WinPygame   ] trying without antialiasing
                [INFO   ] [GL          ] OpenGL version <2.1 Mesa 10.1.3>
                [INFO   ] [GL          ] OpenGL vendor <Intel Open Source Technology Center>
                [INFO   ] [GL          ] OpenGL renderer <Mesa DRI Intel(R) Ironlake Mobile >
                [INFO   ] [GL          ] OpenGL parsed version: 2, 1
                [INFO   ] [GL          ] Shading version <1.20>
                [INFO   ] [GL          ] Texture max size <8192>
                [INFO   ] [GL          ] Texture max units <16>
                [INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
                [INFO   ] [Text        ] Provider: pygame(['text_sdl2'] ignored)
                {}                     #<<< note the emtpy ids I printed out
                 Traceback (most recent call last):
                   File "main.py", line 169, in <module>
                     MineSweeperApp().run()
                   File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 799, in run
                     root = self.build()
                   File "main.py", line 163, in build
                     return Manager()
                   File "/usr/lib/python2.7/dist-packages/kivy/uix/screenmanager.py", line 844, in __init__
                     super(ScreenManager, self).__init__(**kwargs)
                   File "/usr/lib/python2.7/dist-packages/kivy/uix/floatlayout.py", line 66, in __init__
                     super(FloatLayout, self).__init__(**kwargs)
                   File "/usr/lib/python2.7/dist-packages/kivy/uix/layout.py", line 66, in __init__
                     super(Layout, self).__init__(**kwargs)
                   File "/usr/lib/python2.7/dist-packages/kivy/uix/widget.py", line 269, in __init__
                     Builder.apply(self)
                   File "/usr/lib/python2.7/dist-packages/kivy/lang.py", line 1837, in apply
                     self._apply_rule(widget, rule, rule)
                   File "/usr/lib/python2.7/dist-packages/kivy/lang.py", line 1942, in _apply_rule
                     child = cls(__no_builder=True)
                   File "main.py", line 43, in __init__
                     self.grid = self.ids["grid"]
                 KeyError: 'grid'
                

                kv 文件:

                #:kivy 1.8.0
                
                <RootWidget>:
                    GridLayout:
                        id: grid
                        size: root.size
                        cols: root.sides
                
                <Blank>:
                    background_color: 1, 1, 1, 1
                    background_disabled_down: "kivy_white_bg.png"
                    on_press: self.parent.parent.sweep(self)
                
                <Mine>:
                    background_color: 1, 1, 1, 1
                    background_disabled_down: "kivy_white_bg.png"
                    on_press: self.parent.parent.sweep(self)
                
                <TryAgain>:
                    anchor_x: 'center'
                    anchor_y: 'center'
                    BoxLayout:
                        size: root.size
                        orientation: 'vertical'
                        padding_bottom: '20dp'
                
                        Label:
                            font_size: '20dp'
                            text: root.text
                
                        BoxLayout:
                            size_hint: 1, .3
                            spacing: 10
                            padding: 10
                            Button:
                                size_hint: .4, 1
                                font_size: '20dp'
                                text: "yes"
                                on_press: app.stop(); app.run()
                            Button:
                                size_hint: .4, 1
                                font_size: '20dp'
                                text: "no"
                                on_press: root.quit()
                
                <Menu>:
                    GridLayout:
                        rows: 2
                        Button:
                            text: "8x8"
                            on_press: root.manager.current = 'game_screen'
                        Button:
                            text: "16x16"
                            on_press: root.manager.current = 'game_screen'
                        Button:
                            text: "30x16"
                            on_press: root.manager.current = 'game_screen'
                        Button:
                            text: "custom"
                            on_press: root.manager.current = 'game_screen'
                
                <Manager>:
                    id: _manager
                    menu: menu
                    game: game
                    current: menu_screen
                
                    Menu:
                        id: menu
                        manager: _manager
                        name: 'menu_screen'
                
                    RootWidget:
                        id: game
                        manager: _manager
                        name: 'game_screen'
                

                ma​​in.py:

                #!/usr/bin/env python
                
                from random import sample
                import sys
                import kivy
                kivy.require('1.8.0')
                from kivy.app import App
                from kivy.core.window import Window
                from kivy.uix.widget import Widget
                from kivy.uix.button import Button
                from kivy.properties import NumericProperty, ListProperty, StringProperty, ObjectProperty
                from kivy.uix.gridlayout import GridLayout
                from kivy.uix.modalview import ModalView
                from kivy.uix.screenmanager import ScreenManager, Screen
                from kivy.clock import Clock
                
                class Blank(Button):
                
                    index = ListProperty([0, 0])
                    count = NumericProperty(0)
                
                    def __init__(self, **kwargs):
                        super(Blank, self).__init__(**kwargs)
                
                
                class Mine(Button):
                
                    index = ListProperty([0, 0])
                    count = NumericProperty(0) # not really necessary
                
                    def __init__(self, **kwargs):
                        super(Mine, self).__init__(**kwargs)
                
                
                class RootWidget(Screen):
                
                    sides = NumericProperty(10)
                    mine_count = NumericProperty(20)
                
                    def __init__(self, **kwargs):
                        super(RootWidget, self).__init__(**kwargs)
                        self.grid = self.ids["grid"]
                
                        # generate random mine indices
                        mines = sample(xrange(self.sides**2), self.mine_count)
                
                        x, y = -1, 0
                        for i in xrange(self.sides**2):
                            if x == self.sides - 1:
                                x = 0
                                y += 1
                            else:
                                x += 1
                
                            if i not in mines:
                                b = Blank(index=[x, y])
                
                            else:
                                b = Mine(index=[x, y])
                            self.grid.add_widget(b)
                
                        # record mine, blank and safe blank indices
                        self.all_btns = [c.index for c in self.grid.children]
                        self.mines = [c.index for c in self.grid.children if isinstance(c, Mine)]
                        self.blanks = [c.index for c in self.grid.children if isinstance(c, Blank)]
                        # a safe blank has no adjacent mines
                        self.safe_blanks = [c.index for c in self.grid.children if self.is_safe(c)]
                
                        # give each btn an 'adjacent mines count'
                        for x, y in self.all_btns:
                            btn = self.get_child_by_index([x, y])
                            for index in self.field(x, y):
                                if index in self.mines:
                                    btn.count += 1
                
                    def field(self, x, y):
                        """ the minefield surrounding a btn """
                        field = [[x-1, y], [x+1, y], [x, y+1], [x, y-1],
                            [x+1, y+1], [x-1, y-1], [x+1, y-1], [x-1, y+1]]
                
                        get = self.get_child_by_index        
                        return [i for i in field if i in self.all_btns and get(i).disabled == False]
                
                    def sweep(self, instance):
                        instance.disabled = True
                
                        if instance.index in self.mines: 
                            print "Boom!"              # It's a mine! You lose
                            instance.text = "Boom!"
                            self.game_over() 
                
                        pressed = sum(1 for c in self.grid.children if c.disabled == True)
                        print pressed
                        if self.sides**2 - pressed == self.mine_count:
                            self.game_over(win=True)
                
                        if instance.count > 0:
                            instance.text = str(instance.count)
                            instance.disabled = True
                            return
                        else:
                            x, y = instance.index
                
                            for index in self.field(x, y):
                                if index not in self.mines:
                                    blank = self.get_child_by_index(index)
                                    blank.disable = True
                                    if blank.count > 0:
                                        blank.text = str(blank.count)
                                    self.sweep(blank)
                
                    def is_safe(self, btn):
                        x, y = btn.index
                        for index in self.field(x, y):
                            if index in self.mines:
                                return False
                        return True
                
                    def get_child_by_index(self, index):
                        for child in self.grid.children:
                            if child.index == index:
                                return child
                
                    def game_over(self, q=False, win=False):
                        if q == True:
                            sys.exit()
                
                        if win == True:
                            result = "Win"
                        elif win == False:
                            result = "lost"
                
                        view = TryAgain(
                            size_hint = (None, None),
                            width = self.width/2,
                            height = self.height/2,
                            center = self.center,
                            text = "You {}! Try Again?".format(result))
                        view.open()
                
                class TryAgain(ModalView):
                
                    text = StringProperty('')
                
                    def quit(self):
                        sys.exit()
                
                class Menu(Screen):
                    pass
                
                
                class Manager(ScreenManager):
                
                    menu = ObjectProperty(None)
                    game = ObjectProperty(None)
                
                
                class MineSweeperApp(App):
                
                    def build(self):
                        return Manager()
                
                
                
                if __name__ == "__main__":
                
                    MineSweeperApp().run()
                

                推荐答案

                在原始 Widget 完成实例化之前,不会应用 kv 规则.在这种情况下,您的 Manager 小部件是初始小部件 - 它反过来创建其他小部件,包括 RootWidget.这意味着您的 RootWidget.__init__ 中的 ids 尚未填充!它们将在 Manager 完成实例化后立即出现 - 所以最好的方法是延迟其余的初始化,如下所示:

                kv rules are not applied until the original Widget has finished instantiating. In this case, your Manager widget is the initial widget - it, in turn, creates the other widgets including RootWidget. This means that in your RootWidget.__init__ the ids are not yet populated! They will be as soon as Manager finishes instantiating - so the best approach is to just delay the rest of your initialization, like so:

                class RootWidget(Screen):
                    def __init__(self, **kwargs):
                        super(RootWidget, self).__init__(**kwargs)
                        Clock.schedule_once(self._finish_init)
                
                    def _finish_init(self, dt):
                        self.grid = self.ids.grid
                        # etc
                

                这篇关于为什么我无法访问 Screen.ids?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                上一篇:如何使 LAN 客户端可以发现服务器 下一篇:同时运行多个相互通信的 Kivy 应用程序

                相关文章

                最新文章

              2. <i id='Pw5Tz'><tr id='Pw5Tz'><dt id='Pw5Tz'><q id='Pw5Tz'><span id='Pw5Tz'><b id='Pw5Tz'><form id='Pw5Tz'><ins id='Pw5Tz'></ins><ul id='Pw5Tz'></ul><sub id='Pw5Tz'></sub></form><legend id='Pw5Tz'></legend><bdo id='Pw5Tz'><pre id='Pw5Tz'><center id='Pw5Tz'></center></pre></bdo></b><th id='Pw5Tz'></th></span></q></dt></tr></i><div id='Pw5Tz'><tfoot id='Pw5Tz'></tfoot><dl id='Pw5Tz'><fieldset id='Pw5Tz'></fieldset></dl></div>

                  1. <small id='Pw5Tz'></small><noframes id='Pw5Tz'>

                      <bdo id='Pw5Tz'></bdo><ul id='Pw5Tz'></ul>
                    <legend id='Pw5Tz'><style id='Pw5Tz'><dir id='Pw5Tz'><q id='Pw5Tz'></q></dir></style></legend>

                  2. <tfoot id='Pw5Tz'></tfoot>