Le menu déroulant ne fonctionne pas dans le plus récent. Il apparaît et se ferme sans raison. Face à ce problème uniquement sur la construction Android avec la chaîne d'outils android_new
buildozer
from kivy.app import App
from kivy.lang import Builder
kv = '''
BoxLayout:
orientation: 'vertical'
BoxLayout:
size_hint_y: None
height: '50sp'
Button:
id: button
text: 'Open dropdown'
Widget:
DropDown:
id: dropdown
on_parent: self.dismiss()
Button:
size_hint_y: None
text: 'item 1'
Button:
size_hint_y: None
text: 'item 2'
Button:
size_hint_y: None
text: 'item 3'
'''
class MyApp(App):
def build(self):
self.root = Builder.load_string(kv)
self.root.ids.button.bind(on_release=self.root.ids.dropdown.open)
return self.root
MyApp().run()
Je pense que c'est un bogue dans stable (du moins c'est de là que vient ce code) et est corrigé dans master. Pour être plus précis, voici ce que vous voyez :
tout semble bien jusqu'à présent, _pourtant_ la logique derrière DropDown est qu'un utilisateur est censé l' attacher à quelque chose (via son propre comportement avec Dropdown.open(<widget>)
) et _pas_ l' ajouter _en tant qu'enfant_ à un widget. Eh bien, du moins pas de cette façon lorsque vous essayez de le cacher avec on_parent: self.dismiss()
parce que vous l'avez mal utilisé dès le début. Voyez ce qui se passe ensuite (jeu de mots :D ) !
<widget>.bind(<stuff>)
transmet un argument à la méthode DropDown.open()
- l'instance du boutonon_parent
DropDown est mis à jourAlors, que faire maintenant ? Tout d'abord, vous devez arrêter d'utiliser on_parent
cette façon et faire soit :
<MyDropDown>: # make a class in python (or use "@DropDown" and Factory)
text: 'blah'
# and *don't* add it as a child manually
qui ne fait que la règle KV elle-même sans l'utiliser directement comme enfant (comme une comparaison classe vs instance) ou si vous voulez opter pour le comportement d'ajout de widget, utilisez Spinner
car il est construit à cet effet.
Théoriquement, vous pourrez peut-être délier l'événement on_parent
bien que je ne sois pas sûr que ce soit directement dans on_parent
ou seulement de l'extérieur, mais c'est juste une mauvaise façon de "faire fonctionner" , donc je ne vais pas l'écrire. ??
Merci. J'ai utilisé DropDown
comme nouvelle classe et cela a fonctionné
Pourriez-vous expliquer comment utiliser @DropDown dans le fichier kv ?
J'ai kivy 1.10.1, windows 10, python 3.7 et cela fonctionne pour moi si je n'écris pas on_parent: self.dismiss() (ce que je ne sais pas ce qu'il fait)
Mettre le on_parent: self.dismiss()
sur le bouton fonctionne comme prévu. Il n'ouvrira pas automatiquement le DropDown lors du premier lancement de l'application et il ne fermera pas automatiquement le DropwDown une fois qu'il est ouvert.
Remplacez l'appel par : on_parent: dropdown.dismiss()
.
C'est un peu "hacky" mais ça marche bien.
#:kivy 1.0
<InputFileDropDown>:
Button:
id: btn
text: 'Input File'
on_parent: dropdown.dismiss()
on_release: dropdown.open(self)
size_hint_y: None
height: 35
DropDown:
id: dropdown
on_select: btn.text = '{}'.format(args[1])
Button:
text: 'First Item'
size_hint_y: None
height: 35
on_release: dropdown.select('First Item')
Label:
text: 'Second Item'
size_hint_y: None
height: 35
Button:
text: 'Third Item'
size_hint_y: None
height: 35
on_release: dropdown.select('Third Item')
'InputFileDropDown' est un BoxLayout fyi.
@GaryBer
... la logique derrière DropDown est qu'un utilisateur est censé l'attacher à quelque chose (via son propre comportement avec Dropdown.open(
)) et ne pas l'ajouter en tant qu'enfant à un widget. ...
Commentaire le plus utile
Mettre le
on_parent: self.dismiss()
sur le bouton fonctionne comme prévu. Il n'ouvrira pas automatiquement le DropDown lors du premier lancement de l'application et il ne fermera pas automatiquement le DropwDown une fois qu'il est ouvert.Remplacez l'appel par :
on_parent: dropdown.dismiss()
.C'est un peu "hacky" mais ça marche bien.
'InputFileDropDown' est un BoxLayout fyi.