关于python:Kivy-类实例的碰撞点

Kivy - Collide points of class instance

我的以下代码目标非常简单:

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

2:当我按下TextInput并在外面按下时,hint_text显示旧值。

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

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

我想知道是否有一种方法可以使我正在触摸的小部件returnid:成为函数,而无需从每个StorageBox实例中调用方法。

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

您可以在
剪辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
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()

这是您要执行的操作的完整示例,您必须修改外观以使其适合您的应用程序。如果您有任何疑问,请告诉我。

main.py

1
2
3
4
5
6
7
8
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<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"