Kivy-类实例的碰撞点

时间:2019-03-18 05:40:56

标签: python kivy

我下面的代码目标很简单:

1:当我按TextInput时,hint_text清除,出现'+',我可以键入要添加的值。

2:当我按TextInput然后在外部按hint_text时,显示旧值。

3:与p中相同。 2当我按其他TextInput时。

我已经实现了目标,但是代码量和复杂性非常糟糕,我相信这里有很多简单的方法。

我想知道是否有一种方法可以使我正在触摸的窗口小部件returnid:互不影响,而不必从每个StorageBox实例中调用方法。

请记住,此应用程序中将有更多输入,而不仅仅是两次。我添加了10个输入,并且可以正常工作,但是代码很难维护。

您可以在 Clip

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 个答案:

答案 0 :(得分:1)

这是您想要做的一个完整的工作示例,您必须修改外观以使其适合您的应用程序。如果您有任何问题,请告诉我。

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"