Мой код Kivy не обнаруживает установку флажкаPython

Программы на Python
Ответить
Anonymous
 Мой код Kivy не обнаруживает установку флажка

Сообщение Anonymous »

Недавно я попробовал Kivy для личного проекта, который хотел реализовать: приложения, позволяющего создать персонажа DnD с некоторыми деталями. Этот персонаж будет храниться в файле JSON и загружаться на главном экране. Проблема в том, что при использовании флажков для выбора пола это вообще не работает, и я не могу найти проблему.
Вот файл main.py:

Код: Выделить всё

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.graphics import Color, Line
from kivy.uix.button import Button
from kivy.properties import ObjectProperty, ListProperty
import random
import json
import os

class MainScreen(Screen):
def get_random_color(self):
# Returns a random RGBA color
return [random.random() for _ in range(3)] + [0.8]

def add_character_button(self, character_data):
# Create a button for each saved character with a random color and only the name
button = Button(
text=character_data["name"],
size_hint_y=None,
height=50,
background_normal='',
background_color=character_data['color']
)
button.custom_color = button.background_color.copy()
button.bind(pos=self.update_border, size=self.update_border)

# Add a border to the button
with button.canvas.before:
Color(0, 0, 0, 1)  # Set black color for border
self.border_line = Line(rectangle=(button.x, button.y, button.width, button.height), width=1)

button.bind(on_release=lambda btn: self.show_character_details(character_data))

self.ids.character_list.add_widget(button)

def update_border(self, button, _):
# Update border position and size when button size or position changes
self.border_line.rectangle = (button.x, button.y, button.width, button.height)

def load_user_characters(self):
# Load characters from a JSON file and add them to the screen
if os.path.exists('characters.json'):
with open('characters.json', 'r') as f:
characters = json.load(f)
for character in characters:
self.add_character_button(character)

def show_character_details(self, character_data):
character_details_screen = self.manager.get_screen('character_details')
character_details_screen.set_character_data(character_data)  # Pass character data
self.manager.current = 'character_details'

class SecondScreen(Screen):
character_name = ObjectProperty(None)
character_age = ObjectProperty(None)
character_power1 = ObjectProperty(None)
character_power2 = ObjectProperty(None)

def save_character(self):
main_screen = self.manager.get_screen('main')
name = self.ids.character_name.text
age = self.ids.character_age.text
gender = 'Man' if self.ids.man_checkbox.active else 'Woman' if self.ids.woman_checkbox.active else 'Other'
power1 = self.ids.character_power1.text
power2 = self.ids.character_power2.text
color = main_screen.get_random_color()

character_data = {
'name': name,
'age': age,
'gender': gender,
'power1': power1,
'power2': power2,
'color': color
}

# Save character to the list
self.save_characters_to_file(character_data)

# Add button to the main screen dynamically
main_screen.add_character_button(character_data)

# Clear the inputs after saving
self.ids.character_name.text = ''
self.ids.character_age.text = ''
self.ids.character_power1.text = ''
self.ids.character_power2.text = ''
self.ids.man_checkbox.active = False
self.ids.woman_checkbox.active = False

# Switch back to the main screen
self.manager.current = 'main'

def save_characters_to_file(self, new_character):
characters = []

# Load existing characters from file if it exists
if os.path.exists('characters.json'):
with open('characters.json', 'r') as f:
characters = json.load(f)

# Add the new character
characters.append(new_character)

# Save updated character list to file
with open('characters.json', 'w') as f:
json.dump(characters, f)

selected_gender = None
def set_gender(self, checkbox, value):
if value == True:   # If this checkbox is active
# Uncheck the others
if checkbox == self.ids.man_checkbox:
self.ids.woman_checkbox.active = False
elif checkbox == self.ids.woman_checkbox:
self.ids.man_checkbox.active = False

class CharacterDetailsScreen(Screen):
character_color = ListProperty([1, 1, 1, 1]) #default
character_data = None #default
def on_enter(self):
if self.character_data:  # Check if character_data is set
self.ids.character_name.text = self.character_data['name']
self.ids.character_age.text = self.character_data['age']
self.ids.character_gender.text = self.character_data['gender']
self.ids.character_power1.text = self.character_data['power1']
self.ids.character_power2.text = self.character_data['power2']
self.character_color = self.character_data['color']

def set_character_data(self, character):
self.character_data = character  # Store character data

class RosterApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(SecondScreen(name='second'))
sm.add_widget(CharacterDetailsScreen(name='character_details'))

# Load characters into the main screen when the app starts
sm.get_screen('main').load_user_characters()

return sm

if __name__ == '__main__':
RosterApp().run()

И мой файл Kivy:

Код: Выделить всё

:
FloatLayout:
orientation: 'vertical'

# Light yellow background
FloatLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'img.png'

# Round button in the bottom right corner
Button:
text: ""
size_hint: None, None
size: 50, 50
pos_hint: {'right': 0.95, 'bottom': 0.05}
background_normal: 'plus.webp'
background_color: 0.737, 0.635, 0.514, 1 # light almost-off golden
border: (50, 50, 50, 50)  # Simulates a round border
canvas.before:
Color:
rgba: 0.086, 0.086, 0.086, 0.75  # Same dark gray color
Ellipse:  # Draw an ellipse to make the button round
pos: self.pos
size: self.size
on_release:
app.root.current = 'second'

# dark gray top bar with app name
FloatLayout:
size_hint_y: None
height: 50
pos_hint: {'top': 1}
canvas.before:
Color:
rgba: 0.086, 0.086, 0.086, 0.75  # dark gray color
Rectangle:
pos: self.pos
size: self.size
Label:
text: "DnD Roster Panel"
color: 1, 1, 1, 1  # white text
pos_hint: {'center_x': 0.5, 'center_y': 0.5}

ScrollView:
size_hint: (1, 0.8)
pos_hint: {'top': 0.9}
BoxLayout:
id: character_list
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height  # Adjusts height to fit content
spacing: 10
padding: 10

:
FloatLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'img.png'

FloatLayout:
orientation: 'vertical'
FloatLayout:
size_hint_y: None
height: 50
pos_hint: {'top': 1}
canvas.before:
Color:
rgba: 0.086, 0.086, 0.086, 0.75  # dark gray color
Rectangle:
pos: self.pos
size: self.size
Label:
text: "DnD Roster Panel"
color: 1, 1, 1, 1  # white text
pos_hint: {'center_x': 0.5, 'center_y': 0.5}

ScrollView:
size_hint:  1, 0.85  # Make it take up the remaining space
pos_hint: {'top': 0.85}
do_scroll_x: False  # Disable horizontal scrolling

BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
padding: [20, 20, 20, 20]  # Add some padding for spacing
spacing: 20  # Add some space between elements

Label:
text: 'Name'
color: 1, 1, 1, 1
halign: "center"

TextInput:
id: character_name
hint_text: ""
multiline: False
size_hint_y: None
height: 40

Label:
text: 'Age'
color: 1, 1, 1, 1
halign: "center"

TextInput:
id: character_age
hint_text: ""
multiline: False
input_filter: 'int'
size_hint_y: None
height: 40

Label:
text: 'Select Gender'
color: 1, 1, 1, 1
halign: "center"

GridLayout:
cols: 2
spacing: 40
padding: 20
size_hint_y: None
height: self.minimum_height
Label:
text: "Man"
CheckBox:
id: man_checkbox
on_active: root.set_gender(self, self.active)  # Uncheck female if male is checked

Label:
text: "Woman"
CheckBox:
id: woman_checkbox
on_active: root.set_gender(self, self.active)  # Uncheck male if female is checked

Label:
text: 'First Power'
color: 1, 1, 1, 1
halign: "center"

TextInput:
id: character_power1
hint_text: ""
multiline: False
size_hint_y: None
height: 40

Label:
text: 'Second Power'
color: 1, 1, 1, 1
halign: "center"

TextInput:
id: character_power2
hint_text: ""
multiline: False
size_hint_y: None
height: 40

Button:
text: "Save Character"
size_hint_y: None
height: 50
on_release:
root.save_character()  # Call save_character method

:
FloatLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'img.png'

FloatLayout:
orientation: 'vertical'
FloatLayout:
size_hint_y: None
height: 50
pos_hint: {'top': 1}
canvas.before:
Color:
rgba: self.parent.parent.character_color
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'DnD Roster Panel'
color: 1, 1, 1, 1  # white text
pos_hint: {'center_x': 0.5, 'center_y': 0.5}

Label:
id: character_name
text: 'Name'
size_hint_y: None
pos_hint: {'center_x': 0.5, 'top': 0.85}
height: 20
font_size: 30

GridLayout:
cols: 2
spacing: 10
padding: 20
size_hint_y: None
height: self.minimum_height  # Adjusts height to fit content

# Age
Label:
text: "Age: "
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: 1, 1, 1, 1  # Black border color
Line:
rectangle: (self.x, self.y, self.width, self.height)

Label:
id: character_age
text:  "Age:"
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: 1, 1, 1, 1  # Black border color
Line:
rectangle: (self.x, self.y, self.width, self.height)

# Gender
Label:
text: "Gender: "
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: 1, 1, 1, 1  # Black border color
Line:
rectangle: (self.x, self.y, self.width, self.height)

Label:
id: character_gender
text: "Gender:"
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: 1, 1, 1, 1  # Black border color
Line:
rectangle: (self.x, self.y, self.width, self.height)

# First Power
Label:
text: "First Power:"
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: 1, 1, 1, 1  # Black border color
Line:
rectangle: (self.x, self.y, self.width, self.height)

Label:
id: character_power1
text: "First Power:"
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: 1, 1, 1, 1  # Black border color
Line:
rectangle: (self.x, self.y, self.width, self.height)

# Second Power
Label:
text: "Second Power:"
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: 1, 1, 1, 1  # Black border color
Line:
rectangle: (self.x, self.y, self.width, self.height)

Label:
id: character_power2
text: "Second Power:"
size_hint_y: None
height: 50
canvas.before:
Color:
rgba: 1, 1, 1, 1  # Black border color
Line:
rectangle: (self.x, self.y, self.width, self.height)

Button:
text: ""
size_hint: None, None
size: 50, 50
pos_hint: {'left': 0.95, 'bottom': 0.05}
background_normal: 'back.png'
background_color: 0.737, 0.635, 0.514, 1 # light almost-off golden
border: (50, 50, 50, 50)  # Simulates a round border
canvas.before:
Color:
rgba: 0.086, 0.086, 0.086, 0.75  # Same dark gray color
Ellipse:  # Draw an ellipse to make the button round
pos: self.pos
size: self.size
on_release:
app.root.current = 'main'
Мне бы хотелось, чтобы приложение позволяло вам устанавливать и снимать флажки, но ограничивало выбор только одним полем (только один пол).
Сам код тоже может быть очень запутанным, но на данный момент он работает нормально XD

Подробнее здесь: https://stackoverflow.com/questions/791 ... -selection
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»