• B правой части каждого сообщения есть стрелки и . Не стесняйтесь оценивать ответы. Чтобы автору вопроса закрыть свой тикет, надо выбрать лучший ответ. Просто нажмите значок в правой части сообщения.

Python kivy - изменение текста по нажатию на кнопку

26.11.2020
10
0
BIT
0
Всем привет!
Я хочу написать игрульку на python kivy (turn-based симулятор города).
У меня кнопки распологаются снизу, текст сверху. Я поместил кнопки, мне нужна кнопка "Закончить ход". Я ее добавил, но теперь нужно реализовать turn-based систему.
Вот мой код:
Python:
from kivy.app import App

from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.config import Config

Config.set('graphics', 'resizable', '0')
Config.set('graphics', 'height', '480')
Config.set('graphics', 'width', '800')

class CityGame(App):

    def build(self):
        global build_popup, month, menu_text
        month = 1
        year = 2015
        menu_text = "Дата: " + str(month) + "." + str(year)
        # Строить
        gl_2 = GridLayout(rows=3, padding=[7, 7, 7, 7], spacing=[7])
        gl_2.add_widget( Button(text='Жильё'))
        gl_2.add_widget( Button(text='Социальное'))
        gl_2.add_widget( Button(text='Обеспечние'))
        gl_2.add_widget( Button(text='Развлечения'))
        gl_2.add_widget( Button(text='Коммерция'))
        gl_2.add_widget( Button(text='Индустрия'))
        gl_2.add_widget( Button(text='Постройки'))
        close_button = Button(text='Закрыть')
        gl_2.add_widget( close_button )
        build_popup = Popup(title='Что строим?', content=gl_2, size=(300, 300))
        close_button.bind(on_press=build_popup.dismiss)
        # Начальный экран
        bl = BoxLayout(orientation='vertical', padding=25)
        self.lbl = Label(text="0", font_size = 20)
        bl.add_widget( self.lbl )
        gl = GridLayout(cols=3, padding=[20, 20, 20, 0], spacing=[15])
        gl.add_widget( Button(text='Меню'))
        gl.add_widget( Button(text='Строить', on_press=self.bp_open))
        gl.add_widget( Button(text='Завершить ход'))
        gl.add_widget( Button(text='Статистика'))
        bl.add_widget( gl )
        return bl
    def bp_open(self, instance):
        build_popup.open()

if __name__ == "__main__":
    CityGame().run()
Нужны переменные month, year, menu_text
Через каждый ход month увеличивается на 1. Если month = 12, year увеличивается на 1, month обнуляется.
Заранее спасибо
 
Нужны переменные month, year, menu_text
Через каждый ход month увеличивается на 1. Если month = 12, year увеличивается на 1, month обнуляется.
Заранее спасибо
Создайте отдельное поле класса счётчик ходов и метод который будет его увеличивать

Python:
class CityGame(App):
    # Добавляем 3 свойства класса.
    turns = 0
    month = 1
    year = 2015
   
    def turns_incrementer(self):
        # Метод увеличивает количество ходов на 1
        self.turns += 1
   
    def year_incrementer(self):
        # Метод увеличивает количество годов
        if self.month == 12:
            self.month = 1
            self.year += 1

Ну а дальше в методе, который будет у вас запускать следующий код, просто вызывайте нужные методы
Python:
    def new_turn(self):
        self.turns_incrementer()
        self.year_incrementer()

Сам по себе код очень сумбурный, попробуйте для каждой операции выделить свой метод в классе,
иначе скоро попросту не сможете поддерживать ваш код.

Python:
global build_popup, month, menu_text
Не используйте глобальные переменные в классе, для этого есть поля.
 
Создайте отдельное поле класса счётчик ходов и метод который будет его увеличивать

Python:
class CityGame(App):
    # Добавляем 3 свойства класса.
    turns = 0
    month = 1
    year = 2015
  
    def turns_incrementer(self):
        # Метод увеличивает количество ходов на 1
        self.turns += 1
  
    def year_incrementer(self):
        # Метод увеличивает количество годов
        if self.month == 12:
            self.month = 1
            self.year += 1

Ну а дальше в методе, который будет у вас запускать следующий код, просто вызывайте нужные методы
Python:
    def new_turn(self):
        self.turns_incrementer()
        self.year_incrementer()

Сам по себе код очень сумбурный, попробуйте для каждой операции выделить свой метод в классе,
иначе скоро попросту не сможете поддерживать ваш код.

Python:
global build_popup, month, menu_text
Не используйте глобальные переменные в классе, для этого есть поля.
TypeError: new_turn() takes 1 positional argument but 2 were given
 
1612964604073.png
 
Спасибо вам! Только можно теперь изменять значение self.lbl онлайн? Завершился ход и он изменился
Пожалуйста!
Не совсем понятно, что вы вкладываете в слово онлайн - ваша программа не работает с сетью.

Если же вы имеете в виду отображение данных в реальном времени, то тут нужно понять с какой частотой вы хотите это делать.
Например, можно раз в секунду обновлять какое-то значение
Python:
# Импортируем модуль для работы со временем
from datetime import datetime


class CityGame:
    # Добавляем 3 свойства класса.
    turns = 0
    month = 1
    year = 2015

    # Создаём поле для хранения времени
    current_date = datetime.now()

    def turns_incrementer(self):
        # Метод увеличивает количество ходов на 1
        self.turns += 1

    def year_incrementer(self):
        # Метод увеличивает количество годов
        if self.month == 12:
            self.month = 1
            self.year += 1

    def on_press(self):
        self.turns_incrementer()
        self.year_incrementer()
        print("Текущий ход: ", self.turns)
        print("Текущий год: ", self.year)
        print("Текущий месяц: ", self.month)

    def start_refreshing(self):
        # Создаём бесконечный цикл
        # В переменную пишем текущую секунду
        while second := datetime.now().second:
            # Если текущая секунда не равна секунде из поля
            # Переприсваиваем значение и выполняем какой-то код
            if second != self.current_date.second:
                self.current_date = datetime.now()
                # Например печатаем текущее время
                print(datetime.now(), "\n")


game = CityGame()
game.on_press()
game.start_refreshing()
on_line.gif

Более правильным подходом в вашем случае будет использование модуля ,
который выполняет все операции параллельно.
 
Пожалуйста!
Не совсем понятно, что вы вкладываете в слово онлайн - ваша программа не работает с сетью.

Если же вы имеете в виду отображение данных в реальном времени, то тут нужно понять с какой частотой вы хотите это делать.
Например, можно раз в секунду обновлять какое-то значение
Python:
# Импортируем модуль для работы со временем
from datetime import datetime


class CityGame:
    # Добавляем 3 свойства класса.
    turns = 0
    month = 1
    year = 2015

    # Создаём поле для хранения времени
    current_date = datetime.now()

    def turns_incrementer(self):
        # Метод увеличивает количество ходов на 1
        self.turns += 1

    def year_incrementer(self):
        # Метод увеличивает количество годов
        if self.month == 12:
            self.month = 1
            self.year += 1

    def on_press(self):
        self.turns_incrementer()
        self.year_incrementer()
        print("Текущий ход: ", self.turns)
        print("Текущий год: ", self.year)
        print("Текущий месяц: ", self.month)

    def start_refreshing(self):
        # Создаём бесконечный цикл
        # В переменную пишем текущую секунду
        while second := datetime.now().second:
            # Если текущая секунда не равна секунде из поля
            # Переприсваиваем значение и выполняем какой-то код
            if second != self.current_date.second:
                self.current_date = datetime.now()
                # Например печатаем текущее время
                print(datetime.now(), "\n")


game = CityGame()
game.on_press()
game.start_refreshing()
Посмотреть вложение 46942

Более правильным подходом в вашем случае будет использование модуля ,
который выполняет все операции параллельно.
Я хочу, чтобы когда нажимали кнопку "завершить ход" происходило увеличение месяца, денег, людей и т.д., а затем все это выводилось на Label. То есть обновляется при завершении хода
 
Я хочу, чтобы когда нажимали кнопку "завершить ход" происходило увеличение месяца, денег, людей и т.д., а затем все это выводилось на Label. То есть обновляется при завершении хода
Ну всё же в описано:
Python:
gl.add_widget( Button(text='Завершить ход').bind(on_press = self.turns_incrementer) )
У объекта Button есть метод bind и в нём свойство on_press - что будет происходить при нажатии на эту кнопку.
 
Ну всё же в описано:
Python:
gl.add_widget( Button(text='Завершить ход').bind(on_press = self.turns_incrementer) )
У объекта Button есть метод bind и в нём свойство on_press - что будет происходить при нажатии на эту кнопку.
Python:
from kivy.app import App

from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.config import Config

Config.set('graphics', 'resizable', '0')
Config.set('graphics', 'height', '480')
Config.set('graphics', 'width', '800')

class CityGame(App):
    month = 1
    year = 2015
    menu_text = "Дата: " + str(month) + "." + str(year)
    def month_incrementer(self):
        self.month += 1
    def year_incrementer(self):
        if self.month == 12:
            self.year += 1
            self.month = 1
    def new_turn(self, instance):
        self.month_incrementer()
        self.year_incrementer()
        self.menu_text = "Дата: " + str(self.month) + "." + str(self.year)
    def build(self):
        global build_popup
        # Строить
        gl_2 = GridLayout(rows=3, padding=[7, 7, 7, 7], spacing=[7])
        gl_2.add_widget( Button(text='Жильё'))
        gl_2.add_widget( Button(text='Социальное'))
        gl_2.add_widget( Button(text='Обеспечние'))
        gl_2.add_widget( Button(text='Развлечения'))
        gl_2.add_widget( Button(text='Коммерция'))
        gl_2.add_widget( Button(text='Индустрия'))
        gl_2.add_widget( Button(text='Постройки'))
        close_button = Button(text='Закрыть')
        gl_2.add_widget( close_button )
        build_popup = Popup(title='Что строим?', content=gl_2, size=(300, 300))
        close_button.bind(on_press=build_popup.dismiss)
        # Начальный экран
        bl = BoxLayout(orientation='vertical', padding=25)
        self.lbl = Label(text=self.menu_text, font_size = 20)
        bl.add_widget( self.lbl )
        gl = GridLayout(cols=3, padding=[20, 20, 20, 0], spacing=[15])
        gl.add_widget( Button(text='Меню'))
        gl.add_widget( Button(text='Строить', on_press=self.bp_open))
        gl.add_widget( Button(text='Завершить ход', on_press=self.new_turn))
        gl.add_widget( Button(text='Статистика'))
        bl.add_widget( gl )
        return bl
    def bp_open(self, instance):
        build_popup.open()

if __name__ == "__main__":
    CityGame().run()
Забабахал такой код, но он не обновляет дату. Можете помочь?
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!