Моя цель приведенного ниже кода довольно проста:
1: Когда я нажимаю TextInput
, hint_text
очищается, появляется '+'
, и я могу ввести значение для добавления.
2: Когда я нажимаю TextInput
, а затем нажимаю вне, hint_text
показывает старое значение.
3: То же, что и на стр. 2, когда я нажимаю на другой TextInput
.
Я достиг цели, но объем кода и сложность ужасны, и я верю, что есть гораздо более простой способ.
Интересно, есть ли способ создать функцию, которая будет return
id:
виджета, к которому я прикасаюсь, без вызова метода из каждого экземпляра StorageBox.
Пожалуйста, имейте в виду, что в этом приложении будет больше входных данных, а не только в два раза. Я добавил 10 входов, и это работает, но код трудно поддерживать.
Вы можете увидеть поведение на
Клип
from kivy.config import Config
Config.set('graphics', 'multisamples', '0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.clock import Clock
kv = """
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManager:
transition: FadeTransition()
StorageScreen:
<StorageButton@Button>
size_hint_y: None
height: 15
text: 'ADD'
<StorageLabel@Label>
<StoragePlusLabel@Label>
size_hint_x: None
width: 10
<StorageInput@TextInput>:
unfocus_on_touch: False
#focus: True
multiline: False
text_size: self.size
halign: "right"
valign: "middle"
markup: True
<StorageBox>
orientation: 'vertical'
size_hint: None, None
size: 50, 50
padding: 1
canvas.before:
Color:
rgba: (0, 0, 0, 1)
Rectangle:
pos: self.pos
size: self.size
on_touch_down: if not self.collide_point(*args[1].pos): root.this_is(True)
on_touch_down: if self.collide_point(*args[1].pos): root.this_is(False)
<Storage>:
StorageBox:
StorageLabel:
text: 'UPC'
StorageBox:
StorageLabel:
text: '1m'
StorageBox:
StorageLabel:
text: '2m'
StorageBox:
StorageLabel:
text: 'LC/LC'
StorageBox:
id: lc_lc_1m
on_touch_down: if not self.collide_point(*args[1].pos): root.touched('lc_lc_1m', False, False)
GridLayout:
cols:3
StoragePlusLabel:
id: lc_lc_1m_lbl
StorageInput:
id: lc_lc_1m_inp
on_touch_down: if self.collide_point(*args[1].pos): root.touched('lc_lc_1m', False, True)
StoragePlusLabel:
StorageButton:
id: lc_lc_1m_btn
on_press: root.touched('lc_lc_1m', True, False)
StorageBox:
id: lc_lc_2m
on_touch_down: if not self.collide_point(*args[1].pos): root.touched('lc_lc_2m', False, False)
GridLayout:
cols:3
StoragePlusLabel:
id: lc_lc_2m_lbl
StorageInput:
id: lc_lc_2m_inp
on_touch_down: if self.collide_point(*args[1].pos): root.touched('lc_lc_2m', False, True)
StoragePlusLabel:
StorageButton:
id: lc_lc_2m_btn
on_press: root.touched('lc_lc_2m', True, False)
<StorageScreen>
Storage:
"""
outside_storage_box = False
class StorageBox(BoxLayout):
def __init__(self, **kwargs):
super(StorageBox, self).__init__(**kwargs)
def this_is(self, val):
global outside_storage_box
outside_storage_box = val
print('outside_storage_box', val)
class Storage(GridLayout):
cols = 3
rows = 2
i = 0
storage = {'lc_lc_1m': '12', 'lc_lc_2m': '33'}
def __init__(self, **kwargs):
super(Storage, self).__init__(**kwargs)
Clock.schedule_once(self.fill)
def fill(self, dt):
print('fill')
for key in self.storage.keys():
self.ids[key+'_lbl'].text = ''
self.ids[key + '_inp'].text = ''
self.ids[key + '_inp'].hint_text = self.storage[key]
def touched(self, key, add, collide):
global outside_storage_box
print(self.i)
self.i += 1
self.key = key
self.inp = self.key + '_inp'
self.lbl = self.key + '_lbl'
self.value = self.ids[self.inp].text
self.add = add
self.collide = collide
print('------------------------------')
print('key', key, 'add', self.add, 'value', self.value, 'outside', outside_storage_box, 'collide', self.collide)
if self.add == False and self.collide == False and outside_storage_box == True:
self.fill(1)
if self.add == False and self.collide == True and outside_storage_box == False:
self.fill(1)
self.ids[self.lbl].text = '+'
self.ids[self.inp].hint_text = ''
if self.add == True and self.collide == False:
try:
int(self.value)
except:
print('Must be integer')
else:
self.storage[self.key] = str(int(self.storage[self.key]) + int(self.value))
self.fill(1)
class StorageScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
sm = Builder.load_string(kv)
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()