Kivy - Botones - Posición y funcionalidad.
Publicado por Jorge Alberto (50 intervenciones) el 15/07/2021 03:31:07
Hola. ¿Qué tal? Estoy practicando con kivy y se me ocurrió hacer un programa que genere un anagrama, el usuario tenga que adivinar cuál es la palabra y que el programa indique si es correcta o no. En sí, conseguí que el programa hiciera eso con el siguiente código. El código es largo, pero creo que lo principal esta en las lineas 124 y 28, donde no sé si build() es la mejor función a usar. No creo que sea lo más práctico o eficiente, pero solamente estoy practicando, asique no busco tanto eso si no que funcione.
El problema esta en que no sé cómo generar una función para un juego nuevo. Se me ocurrió generar otro código que tenga una función __init__, otra new_game y que en la función on_press_new devuelva la función new_game. Hice esto:
Pero al correr la aplicación los botones no funcionan (ya sé que no tienen función, pero ni siquiera puedo hacer click en los mismos) y se crea todo en la parte inferior izquierda muy chico. Dejo una imagen de lo que pasa:

Alguna idea de cómo solucionar cualquiera de los dos problemas? De nuevo, no pretendo, por ahora, ser eficiente, si no que funcione.
PD: la mayoría de las cosas esta en inglés porque estoy practicando con libros y videos en inglés. Si no se entiende algo lo modifico, pero se me hacía muy engorroso cambiarlo acá.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from random import choice, shuffle
from kivy.core.window import Window
Window.clearcolor = (.10, .54, 1, 1)
Window.size = (500,300)
list_of_words = ['ELEPHANT', 'LION', 'COCODRILE', 'MONKEY', 'KANGAROO']
def create_anagram():
# Chooses a word from the list and shuffles the letters to create the anagram
choices = choice(list_of_words)
list_letters = []
for item in choices:
list_letters.append(item)
shuffle(list_letters)
choices = ''.join(list_letters)
return choices
class MainApp(App):
def build(self):
# These are all variables which will be used later on.
self.choices = create_anagram()
self.window = RelativeLayout()
self.font_size = 20
self.letters, self.underscores = [],[]
self.ind = 0 # Index used on chose_letter()
self.size_x, self.size_y = 100, 50
self.pos_x = 0
self.word = '' # will concatonate the letters choosen.
# Adding the buttons to the respectives lists.
for letter in self.choices:
self.window.add_widget(Button(text=letter,
size_hint=(1/len(self.choices), 0.2),
pos_hint = {'x': self.pos_x, 'top': .8},
font_size = self.font_size,
color='#688FF8',
background_color = '#1F48F2',
on_press = self.chose_letter,
disabled = False))
self.underscores.append(Label(text='_',
size_hint=(1/len(self.choices), 0.2),
pos_hint = {'x': self.pos_x, 'top': 0.4},
size=(self.size_x, self.size_y),
font_size = self.font_size,
color = '#FFFFFF'))
self.pos_x += 1/len(self.choices)
# Adding buttons for the letters and the underscores.
for item in self.letters:
self.window.add_widget(item)
for item in self.underscores:
self.window.add_widget(item)
self.RESTART = Button(text='RESTART',
size_hint=(0.2,0.1),
font_size = 12,
pos_hint = {'center_x': .5,'center_y': 0.1},
on_press = self.on_press_restart)
self.window.add_widget(self.RESTART)
return self.window
def chose_letter(self, instance):
# When the user clicks on a letter, it adds that letter to the first empty label and to self.word
if self.ind == len(self.choices): # If we click a button when the word is complete (either correct or incorrect)
return True # This will allow the program not to add 1 to self.ind (and will not cursh)
_choice = instance.text # Gets the text from the button
self.underscores[self.ind].text = _choice # Changes the first underscore for the text in _choice
self.ind += 1 # Adds 1 to the index counter
self.word += _choice # Copies the word created, in order to compare it to the words on the list (in the next line)
# It shows a message, either the word is correct or not.
if len(self.choices) == len(self.word):
if self.word in list_of_words:
self.CONGRAT = Label(text='CONGRATULATIONS! THE WORD IS: ',
size_hint=(.8, .4),
pos_hint = {'center_x':0.5, 'center_y': 0.45},
font_size = self.font_size)
self.window.add_widget(self.CONGRAT)
self.NEW = Button(text='NEW WORD',
size_hint=(0.2,0.1),
font_size = 12,
pos_hint = {'center_x': .5,'center_y': 0.1},
on_press = self.on_press_new)
self.window.add_widget(self.NEW)
else:
self.SORRY = Label(text='SORRY, WORNG WORD!',
size_hint=(.8, .4),
pos_hint = {'center_x':0.5, 'center_y': 0.45},
font_size = self.font_size)
self.window.add_widget(self.SORRY)
def on_press_restart(self, instance):
under_index = 0
for item in self.underscores:
self.underscores[under_index].text = '_'
under_index += 1
self.ind = 0
self.word = ''
# self.window.remove_widget(self.SORRY)
def on_press_new(self, instance):
# self.choices = create_anagram()
print(self.choices)
self.window.remove_widget(self.NEW) # It owrks, but the game doesn't restart.
self.window.remove_widget(self.CONGRAT)
if __name__ == '__main__':
MainApp().run()
El problema esta en que no sé cómo generar una función para un juego nuevo. Se me ocurrió generar otro código que tenga una función __init__, otra new_game y que en la función on_press_new devuelva la función new_game. Hice esto:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from random import choice, shuffle
from kivy.core.window import Window
Window.clearcolor = (.10, .54, 1, 1)
Window.size = (500,300)
list_of_words = ['ELEPHANT', 'LION', 'COCODRILE', 'MONKEY', 'KANGAROO']
def create_anagram():
# Takes a word from the list and shuffles the letters to create the anagram
choices = choice(list_of_words)
list_letters = []
for item in choices:
list_letters.append(item)
shuffle(list_letters)
choices = ''.join(list_letters)
return choices
class Anagram(RelativeLayout):
def __init__(self, **kwargs):
super(Anagram, self).__init__(**kwargs)
# These are all variables which will be used later on.
self.choices = create_anagram()
self.window = RelativeLayout()
self.font_size = 20
self.letters, self.underscores = [],[] # This lists will contain, respectively, the letters of the word and underscores.
self.ind = 0 # Index used on chose_letter()
self.size_x, self.size_y = 100, 50 # Sizes for the labels and button
self.pos_x = 0 # Initial position for the labels and buttons
self.word = '' # will concatonate the letters choosen
self.new_game()
def new_game(self):
with self.canvas.after:
for item in self.choices:
self.letters.append(Button(text=item,
size_hint=(1/len(self.choices), 0.2),
pos_hint = {'x': self.pos_x, 'top': .8},
font_size = self.font_size,
color='#688FF8',
background_color = '#1F48F2',
disabled = False))
self.underscores.append(Label(text='_',
size_hint=(1/len(self.choices), 0.2),
pos_hint = {'x': self.pos_x, 'top': 0.4},
size=(self.size_x, self.size_y),
font_size = self.font_size,
color = '#FFFFFF'))
self.pos_x += 1/len(self.choices)
# Adding buttons for the letters and the underscores.
for item in self.letters:
self.window.add_widget(item)
for item in self.underscores:
self.window.add_widget(item)
class MainAnagramApp(App):
def build(self):
return Anagram()
if __name__ == '__main__':
MainAnagramApp().run()
Pero al correr la aplicación los botones no funcionan (ya sé que no tienen función, pero ni siquiera puedo hacer click en los mismos) y se crea todo en la parte inferior izquierda muy chico. Dejo una imagen de lo que pasa:

Alguna idea de cómo solucionar cualquiera de los dos problemas? De nuevo, no pretendo, por ahora, ser eficiente, si no que funcione.
PD: la mayoría de las cosas esta en inglés porque estoy practicando con libros y videos en inglés. Si no se entiende algo lo modifico, pero se me hacía muy engorroso cambiarlo acá.
Valora esta pregunta


0