UPDATE: ответПочему я не могу получить доступ к Screen.ids?
Ryan P, при условии решения. Однако я принял это решение и немного изменил его, выбросив все данные, которые не были , правильно инициализированы в методе on_enter на RootWidget Экран. Это сработало хорошо.
Класс My RootWidget был подклассифицирован Виджет до сегодняшнего дня, и у меня не было проблем с доступом к его идентификаторам, чтобы получить значение «сетки». Тем не менее, я просто изменил его на подкласс Screen, и теперь он говорит, что по какой-то причине идентификаторы пустые ... Экран имеет идентификаторы и все такое, но по какой-то причине он не регистрирует это Я назначил GridLayout к id '' grid '' в файле kv. Может ли кто-нибудь сказать мне, почему?
отслеживающий:
[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'
киловольт файл:
#: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'
main.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()
из журнала он выглядит, как вы используете v1.9.0_dev. Нет проблем с добавлением идентификатора на экран в v1.8.0. Вы пробовали тот же код с этой версией? – tiktok
У меня нет. Я не уверен, как можно понизить рейтинг – Totem
Можете ли вы разместить больше кода, чтобы он был выполнен, и я попробую его на своей машине? – tiktok