提问人:DR4NKR1D3R 提问时间:8/14/2022 更新时间:8/15/2022 访问量:121
网格布局内的按钮问题 网格布局内的按钮问题
Problem with buttons inside grid layout inside grid layout
问:
你能帮我解决按钮问题吗? 我的布局如下所示(图 1): BoxLayout->GridLayout->GridLayout->Button(x9)
我的问题是我无法更改其他子网格中按钮的文本。看看我这样做的想法:
类:
class SmallGrid(GridLayout):
buttons = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
for i in range(0, 9):
obj = SudokuButton()
self.buttons.append(obj)
self.add_widget(obj)
class BigGrid(GridLayout):
small_grids = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
for i in range(0, 9):
obj = SmallGrid()
self.grids.append(obj)
self.add_widget(obj)
我的主类/伪代码的一小部分:
big_grid = BigGrid()
for i in range(0, 9):
for j in range(0, 9):
self.big_grid.small_grids[i].buttons[j].text = ...
我可以访问其他 SmallGrid() layous 和他们的按钮,但看起来 SmallGrids() 在同一个地方,但它们的按钮在它们预定的位置。
完整的代码在这里(如果你想尝试你的想法):
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.graphics import Rectangle
from kivy.graphics import Color
from kivy.graphics.vertex_instructions import Line
from kivy.properties import NumericProperty, ObjectProperty, StringProperty
from kivy.metrics import dp
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.config import Config
import random
class KivySudokuApp(App):
def build(self):
return Sudoku()
class SmallGrid(GridLayout):
buttons = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
for i in range(0, 9):
obj = SudokuButton()
self.buttons.append(obj)
self.add_widget(obj)
class BigGrid(GridLayout):
grids = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
for i in range(0, 9):
obj = SmallGrid()
self.grids.append(obj)
self.add_widget(obj)
class MenuWidget(RelativeLayout):
pass
class Sudoku(BoxLayout):
original_board = [[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
player_board = [[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
useable_values = numberList=[1, 2, 3, 4, 5, 6, 7, 8, 9]
seconds_passed = 0
minutes_passed = 0
last_key = ""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.orientation = 'vertical'
self.title = Label(text = "KivySudoku",
font_size = self.height * 0.5,
font_name = "label_font.ttf",
color = (0, 0.25, 0.3, 1),
bold = True,
size_hint = (1, 0.1))
self.timer = Label(font_size = self.height * 0.2,
font_name = "label_font.ttf",
color = (0, 0.25, 0.3, 1),
bold = True,
size_hint = (1, 0.05))
self.number = Label(font_size = self.height * 0.2,
font_name = "label_font.ttf",
color = (0, 0.25, 0.3, 1),
bold = True,
size_hint = (1, 0.05))
self.menu = MenuWidget()
self.add_widget(self.menu)
self._keyboard = Window.request_keyboard(self.keyboard_closed, self)
self._keyboard.bind(on_key_down=self.on_key_down)
Clock.schedule_interval(self.update, 1/60)
def on_key_down(self, keyboard, keycode, text, modifiers):
for i in range(1, 10):
if keycode[1] == str(i):
self.last_key = str(i)
return True
def keyboard_closed(self):
self._keyboard.unbind(on_key_down = self.on_key_down)
self._keyboard = None
def original_board_init(self):
for i in range(0, 81):
row = int(i/9)
col = i%9
if self.original_board[row][col] == 0:
random.shuffle(self.useable_values)
for value in self.useable_values:
if self.value_check(row, col, value):
self.original_board[row][col] = value
if self.is_full(self.original_board):
return True
else:
if self.original_board_init():
return True
break
self.original_board[row][col] = 0
def player_board_init(self, to_del):
self.player_board = self.original_board
to_remove = random.sample(range(0, 81), to_del)
for i in to_remove:
row = int(i/9)
col = i%9
self.player_board[row][col] = ""
for i in range(0, 9):
for j in range(0, 9):
self.grid.grids[i].buttons[j].text = str(self.player_board[i][j])
# if self.grid.grid1.buttons[j].text == "":
# self.grid.grid1.buttons[j].disabled = True
def solve_board(self):
for i in range(0, 81):
row = int(i/9)
col = i%9
if self.original_board[row][col] == 0:
for value in range(1,10):
if self.value_check(row, col, value):
self.original_board[row][col] == value
self.solve_board()
self.original_board[row][col] = 0
return False
def is_full(self, board):
for row in range(0, 9):
for col in range(0, 9):
if board[row][col] == 0:
return False
return True
def value_check(self, row, col, value):
R = int(row/3) * 3
C = int(col/3) * 3
for i in range(0, 9):
if self.original_board[i][col] == value:
return False
for j in range(0, 9):
if self.original_board[row][j] == value:
return False
for i in range(R, R + 3):
for j in range(C, C + 3):
if value == self.original_board[i][j]:
return False
return True
def update(self, dt):
self.seconds_passed += dt
self.number.text = "Enter number: " + str(self.last_key)
# for i in range(0, 9):
# for j in range(0, 9):
# self.grid.big_grid.small_grids[i].buttons[j].last_key = self.last_key
self.update_time()
def update_time(self):
if self.seconds_passed > 60:
self.seconds_passed -= 60
self.minutes_passed += 1
seconds = str(format(int(self.seconds_passed), '02'))
minutes = str(format(self.minutes_passed, '02'))
self.timer.text = "Time: " + minutes + ":" + seconds
def easy_button(self):
self.switch_menu()
self.player_board_init(31)
def medium_button(self):
self.switch_menu()
self.player_board_init(51)
def hard_button(self):
self.switch_menu()
self.player_board_init(61)
def switch_menu(self):
self.seconds_passed = 0
self.minutes_passed = 0
self.original_board_init()
self.remove_widget(self.menu)
self.grid = BigGrid()
self.grid.pos_hint = {"center_x": 0.5, "center_y:": 0.5}
self.add_widget(self.title)
self.add_widget(self.timer)
self.add_widget(self.number)
self.add_widget(self.grid)
class SudokuButton(Button):
last_key = ""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.background_normal = ""
self.background_color = (0.2, 0.2, 0.2)
def on_press(self):
if self.last_key != "":
self.text = self.last_key
return super().on_press()
KivySudokuApp().run()
kivysudoku.kv 文件:
#:kivy 2.1.0
Sudoku:
<Sudoku>:
canvas.before:
Color:
rgba: [0.1, 0.1, 0.1, 1]
Rectangle:
pos: self.pos
size: self.size
<BigGrid>:
cols: 3
size_hint: (None, 0.8)
width: self.height
spacing: 4
padding: 8
canvas.before:
Color:
rgba: [0, 0.25, 0.3, 1]
Rectangle:
pos: self.pos
size: self.size
<SmallGrid>:
cols: 3
spacing: 1
canvas.before:
Color:
rgba: [0, 0.25, 0.3, 1]
Rectangle:
pos: self.pos
size: self.size
<MenuWidget>:
canvas.before:
Color:
rgba: 0.1, 0.1, 0.1
Rectangle:
size: self.size
Label:
text: "difficuty"
color: 0, 0.35, 0.4, 1
font_size: self.height * 0.8
font_name: "label_font.ttf"
pos_hint: { "center_x": .5, "center_y": 0.8}
size_hint: 0.4, 0.15
Button:
color: 0, 0.25, 0.3, 1
background_color: 0.95 ,0.95, 0.95, 0.8
font_size: self.height * 0.8
font_name: "label_font.ttf"
text: "easy"
pos_hint: { "center_x": .5, "center_y": 0.6}
size_hint: 0.4, 0.15
on_press: root.parent.easy_button()
background_normal: ""
Button:
color: 0, 0.25, 0.3, 1
background_color: 0.95 ,0.95, 0.95, 0.8
font_size: self.height * 0.8
font_name: "label_font.ttf"
text: "medium"
pos_hint: { "center_x": .5, "center_y": 0.4}
size_hint: 0.4, 0.15
on_press: root.parent.medium_button()
background_normal: ""
Button:
color: 0, 0.25, 0.3, 1
background_color: 0.95 ,0.95, 0.95, 0.8
font_size: self.height * 0.8
font_name: "label_font.ttf"
text: "hard"
pos_hint: { "center_x": .5, "center_y": 0.2}
size_hint: 0.4, 0.15
on_press: root.parent.hard_button()
background_normal: ""
答:
0赞
John Anderson
8/15/2022
#1
问题在于您对 和 使用了类变量。你真的需要它们成为实例变量。只需将您的定义稍微更改为:grids
buttons
class BigGrid(GridLayout):
# grids = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.grids = []
for i in range(0, 9):
obj = SmallGrid()
self.grids.append(obj)
self.add_widget(obj)
和
class SmallGrid(GridLayout):
# buttons = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.buttons = []
for i in range(0, 9):
obj = SudokuButton()
self.buttons.append(obj)
self.add_widget(obj)
评论
0赞
DR4NKR1D3R
8/15/2022
哇,非常感谢。我在这个问题上浪费了一整天。你花了多长时间才看到这一点?
评论