kivy textinput with droplist

0

Witam ponownie. Taki mnimalny.

import kivy
from kivy.app import runTouchApp,stopTouchApp
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout


def f_ForLay(*e): print(e[0],'Layout')
def f_ForTxt(*e): print(e[0],'Text')

layMain=FloatLayout()
mnTxt=TextInput(multiline=False,size_hint=(.4,.06),pos_hint={'top':1})
mnTxt.bind(on_touch_up=f_ForTxt)
layMain.bind(on_touch_up=f_ForLay)
layMain.add_widget(mnTxt)
runTouchApp(layMain)

Dlaczego po kliknięciu w pole poza obszarem textinput funkcja dla textinput się aktywuje. I odwrotnie. Po kliku w textinput pojawia się odpowiedź z funkcji dla Layouta.

Pozdrawiam
Głębicki

0

Eventy propagują się w górę, masz to w dokumentacji. Zgodnie z nią, jak sobie zrobisz:

def f_ForLay(*e):
    print(e[0],'Layout')
    return True

to przestanie.

1

Dla Layout jest git, ale dla TextInput dalej jest Layout Text

No i ma to sens: TextInput siedzi wewnątrz FloatLayout, więc jak klikniesz w niego to najpierw wykrywa to FloatLayout, a potem propaguje się to do TextInput.

Jest jednak coś takiego jak widget.collide_point(x, y) (patrz tutaj), którym można sprawdzać, czy kliknięcie obejmuje jakiś widget, więc można by zrobić coś takiego:

def f_ForLay(layout, touch):
    for child in layout.children:
        if child.collide_point(*touch.pos):
            return True
    print(layout, "Layout")
    return True

def f_ForTxt(text_input, touch):
    print(text_input, "Text")
0

Wielkie dzięki.
Takie tam wypociny. Pewnie można lepiej. Może się komuś przyda. Oczywiście to część większego projektu.

import kivy
from kivy.app import runTouchApp,stopTouchApp
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.button import Button

def f_ForLay(wdg,event):
	for child in wdg.children:
		if child.collide_point(*event.pos):
			return True
	wdg.remove_widget(drpScrl)
	return True
def f_ForTxt(twdg,event):
	if drpScrl in layMain.children: return True
	layMain.add_widget(drpScrl)
	return True
def f_SetTxtToField(*data):
	mnTxt.text=data[0].text
	return None
def f_TxtToBtns(*data):
	sTxtFrom=data[0].text
	for child in drpLay.children:
		if child.text==sTxtFrom:
			print("Już istnieje!") # tu dam popupa z kivy
			return None
	btn=Button(text=sTxtFrom,size_hint=(1,None),height=60) #,pos_hint={'top':.94})
	btn.bind(on_release=f_SetTxtToField)
	drpLay.add_widget(btn)
	data[0].text=""
	return None
layMain=FloatLayout()

drpScrl=ScrollView(do_scroll_y=True,do_scroll_x=False,size_hint=(.5,.5),pos_hint={'top':.94})
drpLay=BoxLayout(orientation='vertical',size_hint=(1,None))
drpLay.bind(minimum_height=drpLay.setter('height')) # ### ### ### ### Important for scroll??!!

for x in range(5):
	btn=Button(text="Btn "+str(x+1),size_hint=(1,None),height=60) #,pos_hint={'top':.94})
	btn.bind(on_release=f_SetTxtToField)
	drpLay.add_widget(btn)

drpScrl.add_widget(drpLay)

mnTxt=TextInput(multiline=False,size_hint=(.4,.06),pos_hint={'top':1})
mnTxt.bind(on_touch_up=f_ForTxt)
mnTxt.bind(on_text_validate=f_TxtToBtns)
layMain.bind(on_touch_up=f_ForLay)
layMain.add_widget(mnTxt)

runTouchApp(layMain)

screenshot-20211125234958.png

Pozdrawiam
Radosław Głębicki

0

Jeszcze jedna dziwna rzecz.
Pole tekstowe nie będzie u góry. Ustawiam je pośrodku i chcę aby lista rozwinęła się poniżej. Odczytuję pozycję pola tekstowego. Mam rozmiar listy z przyciskami. Odejmuję. Ustawiam jako pozycję layoutu z przyciskami, a pojawia mi się w innym miejscu mimo, że odczytana pozycja jest właściwa.

screenshot-20211126024833.png

Dlaczego?

1 użytkowników online, w tym zalogowanych: 0, gości: 1