Kivy - Столкновение точек класса экземпляра - PullRequest
0 голосов
/ 18 марта 2019

Моя цель приведенного ниже кода довольно проста:

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()

1 Ответ

1 голос
/ 18 марта 2019

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

main.py

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView

class MainApp(App):
    pass

MainApp().run()

main.kv

<MyWidget@GridLayout>: 
    cols: 1
    text: ""
    GridLayout:
        rows: 1
        Label:
            text: ""
            id: plus_label
        TextInput:
            id: text_input
            hint_text: root.text  # root.text refers to the text variable at the top of this widget
            on_focus:
                plus_label.text = "+" if self.focus else ""  # If the user clicks in the text input, show the plus sign.
                # If they click outside the text input, hide the plus sign
    Button:
        text: "ADD"
        on_release:
            text_input.hint_text = str(int(text_input.hint_text) + int(text_input.text)) # Do some math using the text and hint text
            text_input.text = ""  # Clear the text





GridLayout:
    rows: 1
    MyWidget:
        text: "8" # This sets the `root.text` variable, which the text input initializes to
    MyWidget:
        text: "3"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...