Instantiate data class from dropdown menu options using on_touch_up

情到浓时终转凉″ 提交于 2020-03-25 12:31:09

问题


I would like to populate MyData with information gathered from dropdown menus that show up in a popup window with "on_touch_up" in AddTouch. That data includes the position of "on_touch_up", in addition to the dropdown data. I am able to print the position within the AddTouch class, but I am having a hard time getting the data further down in my script using (for example: print('from MyMainApp: {}'.format(MyData.pos))).

I am also unable to get "mainbutton" or "dropdown" to show up in a popup window.

Hacking around with this I came up with the following which works, but doesn't do what i need

.py

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.dropdown import DropDown
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.graphics import Color, Rectangle

class AddTouch(Widget):
    def __init__(self, **kwargs):
        super(AddTouch, self).__init__(**kwargs)
        with self.canvas:
            Color(1, 0, 0, 0.5, mode="rgba")
            self.rect = Rectangle(pos=(0, 0), size=(10, 10))
    def on_touch_down(self, touch):
        self.rect.pos = touch.pos
    def on_touch_move(self, touch):
        self.rect.pos = touch.pos
    def on_touch_up(self, touch):
        # final position
        self.pos = touch.pos
        print(self.pos)

class MyPopup(Popup):
    def __init__(self, **kwargs):
        super(MyPopup, self).__init__(**kwargs)
        # create a main button
        self.mainbutton = Button(text='Hello', size_hint=(None, None))
        # create a dropdown with 10 buttons
        self.dropdown = DropDown()
        for index in range(10):
            btn = Button(text='Value %d' % index, size_hint_y=None, height=44)
            btn.bind(on_release=lambda btn: self.dropdown.select(btn.text))
            self.dropdown.add_widget(btn)
        self.mainbutton.bind(on_release=self.dropdown.open)
        self.dropdown.bind(on_select=lambda instance, x: setattr(self.mainbutton, 'text', x))

class MyData:
    def __init__(self, **kwargs):
        super(MyData, self).__init__(**kwargs)
        self.pos=AddTouch.pos

# using kivy screen for consistency
class MainWindow(Screen):
    pass   
class WindowManager(ScreenManager):
    pass    
kv = Builder.load_file("dropd.kv")
class MyMainApp(App):
    def build(self):
        return kv
        print('from MyMainApp: {}'.format(MyData.pos))

if __name__ == "__main__":
    MyMainApp().run()

.kv

WindowManager:
    MainWindow:

<MainWindow>:
    name: "main"
    AddTouch:
        on_touch_up:
            #MyPopup gives 'MyPopup' is not defined, even if I add <MyPopup>: below
            #root.MyPopup gives 'MainWindow' object has no attribute 'MyPopup'

I tried adding a simple dynamic Popup class in the .kv file based on this, but again it says 'MyPopup' is not defined:

.kv

AddTouch
    on_touch_up:
        MyPopup

<MyPopup@Popup>:
    auto_dismiss: False
    Button:
        text: 'Close me!'
        on_release: root.dismiss()

What am I missing (other than experience, ability, and general intelligence)?


回答1:


In addition to adding the line:

self.content = self.mainbutton

to the MyPopup __init__() method, you can trigger the MyPopup creation by modifying your .kv file as:

#:import Factory kivy.factory.Factory

WindowManager:
    MainWindow:

<MainWindow>:
    name: "main"
    AddTouch:
        on_touch_up:
            Factory.MyPopup().open()


来源:https://stackoverflow.com/questions/60385318/instantiate-data-class-from-dropdown-menu-options-using-on-touch-up

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!