Как создать уникальные выпадающие меню на одном экране? - PullRequest
0 голосов
/ 14 ноября 2018

В настоящее время я работаю над созданием довольно простого фитнес-приложения на Python с использованием Kivy. Все шло довольно гладко, но недавно я столкнулся с проблемой при попытке вставить выпадающее меню на один из моих экранов. Я пытаюсь поместить 3 разных выпадающих меню на один экран, который будет возвращать определенные значения, которые я позже буду использовать для основной функции приложения (которая будет генерировать ежедневную программу фитнеса). Проблема в том, что у каждого выпадающего меню есть одна и та же опция. Например, два из выпадающих меню, которые я хочу использовать: «Доступность по времени» (30 минут, 60 минут ... 120 минут) и «Уровень физической подготовки» (шкала 1-3). Но в каждом раскрывающемся меню отображается то же содержимое, что и у меня (например, доступность времени 30 минут, 60 минут ... 120 минут, а затем то же самое для содержимого внутри уровня физической подготовки).

Есть ли у кого-нибудь предложения о том, как сохранить каждое выпадающее меню уникальным на одном экране? Код для моих 2 файлов (один .py и один .kv) прилагаются. В приведенном ниже коде я удалил содержимое раскрывающихся меню, чтобы они были в основном пустыми кнопками.

.py файл:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.base import runTouchApp
import webbrowser
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.properties import ObjectProperty



######################################################################
class KivyTutorRoot(BoxLayout):
    def __init__(self, **kwargs):
        super(KivyTutorRoot, self).__init__(**kwargs)
        #list of previous screens
        self.screen_list = []

    def changeScreen(self, next_screen):
        operations = "Get Fit, Create User".split(',')
        question = None
        #if screen is not already in the list of previous screens...
        if self.ids.kivy_screen_manager.current not in self.screen_list:
            self.screen_list.append(self.ids.kivy_screen_manager.current)

        if next_screen == 'about this app':
            self.ids.kivy_screen_manager.current = "about_screen"
        elif next_screen == 'get fit':
            self.ids.kivy_screen_manager.current = "getFitScreen"


    def onBackBtn(self):
        #check if there are any screens to go back to
        if self.screen_list:
            #if there are screens we can go back to. Then go back to that screen
            self.ids.kivy_screen_manager.current = self.screen_list.pop()
            #the pop() will return the last item from the list, aka the last screen we visited
            #say we don't want to close
            return  True
        #no more screens to go back to, so we close
        return False


###############################################################################
#dropdown menu classes here:
class CustomDropDownTime(DropDown):
    pass
class CustomDropDownGym(DropDown):
    pass



##############################################################################
#This will be a screen for all of the fitness functions
class getFitScreen(Screen):
    top_layout = ObjectProperty(None)
    dd_btn = ObjectProperty(None)
    top_layout2 = ObjectProperty(None)
    dd_btn2 = ObjectProperty(None)
    def __init__(self,*args,**kwargs):
        super(getFitScreen, self).__init__(*args, **kwargs)
        #everything undere this is new code from stackover flow and it works for one. Stops working at GYM
        self.drop_down = CustomDropDownTime()
        dropdown = DropDown()
        #time availability dropdown
        time = ['15-30mins', '30-60mins', '60-90mins','90-120mins']
        for times in time:
            btn = Button(text='%r' %times, size_hint_y=None, height=30)
            btn.bind(on_release=lambda btn: dropdown.select(btn.text))
            dropdown.add_widget(btn)
        mainbutton = Button(text='Time Available', size_hint=(1, 1))
        mainbutton.bind(on_release=dropdown.open)
        dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x))


###############################################################################
#This will be a screen for the charts
class graphScreen(Screen):
    def __init__(self,**kwargs):
        super(graphScreen, self).__init__(**kwargs)


################################################################################
class KivyTutorApp(App):
    def __init__(self, **kwargs):
        super(KivyTutorApp, self).__init__(**kwargs)
        Window.bind(on_keyboard=self.onBackBtn)

    def onBackBtn(self, window,key,*args):
        #if user presses back button
        #27 is the numerical code for back button
        if key == 27:
            return self.root.onBackBtn()
    def build(self):
        return KivyTutorRoot()

    # this next part is so that we can 'get text' from this .py file when running from our .kv file
    def getText(self):
        # you need markup: True to use references like these
        return ("Hey there! \nThis App was built using "
                "[b][ref=kivy]kivy[/ref][/b]\n"
                "Feel free to look at the source code "
                "[b][ref=sour"
                "ce]here[/ref][/b].\n"
                "This app is under the [b][ref=mit]MIT License[/ref][/b]\n"
                "Me: [b][ref=website]@kevin_adrian95[/ref][/b]")

    # this next part is going to make the actual references
    def on_ref_press(self, instance, ref):
        dict = {
            "source": "https://github.com/gopar/Kivy-Tutor",
            # youre going to want to change this to your own github when you finish.
            "website": "https://www.instagram.com/kevin_adrian95/",
            "kivy": "https://kivy.org/#home",
            "mit": "https://github.com/gopar/kivy-Tutor/blob/master/LICENSE"
        }
        webbrowser.open(dict[ref])


KivyTutorApp().run()

.kv файл:

<WrappedLabel@Label>:
size_hint_y: None
height: self.texture_size[1]+(self.texture_size[1]/2)
markup: True
<CustomDropDownTime>:
    Button:
        text: '15-30 mins'
        size_hint_y: None
        height: 44
        on_release: root.select('15-30mins')
    Button:
        text: '30-60 mins'
        size_hint_y: None
        height: 44
         on_release: root.select('30-60min')
    Button:
        text: '60-90 mins'
        size_hint_y: None
        height: 44
        on_release: root.select('60-90mins')
    Button:
        text: '90-120 mins'
        size_hint_y: None
        height: 44
        on_release: root.select('90-120mins')
    <CustomDropDownGym>:
        Button:
            text: 'Yes'
            size_hint_y: None
            height: 44
            on_release: root.select('Yes')
    Button:
        text: 'No'
        size_hint_y: None
        height: 44
        on_release: root.select('No')

< KivyTutorRoot >:
    orientation: "vertical"
    ActionBar:
    ActionView:
        ActionPrevious:
            title: 'Kevin Adrian'
            with_previous: False
        ActionOverflow:
            ActionButton:
                text: "Settings"
                on_press: app.open_settings()
    ScreenManager:
        id: kivy_screen_manager
        StartScreen:
            name: "start_screen"
        AboutScreen:
            id: about_screen
            name: "about_screen"
        getFitScreen:
            id: getFitScreen
            name: "getFitScreen"
<StartScreen@Screen>:
    BoxLayout:
        #settings
        orientation: "vertical"
        padding: root.width * .2, root.height*.1
        spacing: min(root.width, root.height)*.1
    WrappedLabel:
        text: "[b] Kevin Adrian [/b]"
        font_size: min(root.height, root.width) /10
    Button:
        text: "Get Fit"
        font_size: 35
        on_release: app.root.changeScreen(self.text.lower())
    Button:
        text: "Create User"
        font_size: 20
    Button:
        text: "About this app"
        on_release: app.root.changeScreen(self.text.lower())
<AboutScreen@Screen>:
    BoxLayout:
        padding: root.width * .02, root.height*.02
        Label:
            text: app.getText()
            halign: "center"
            markup: True
            font_size: root.height / 20
            text_size: self.width, None
            center_y: .5
            on_ref_press: app.on_ref_press(*args)
<getFitScreen>:
    id: getFitScreen
    top_layout: topLayoutID
    dd_btn: btn_ddID 
    BoxLayout:
        id: topLayoutID
        size_hint: 1, .05
        pos_hint: {'x': 0, 'y': .95}
        Button:
            id: btn_ddID
            text: 'Time Availablity'
            on_release: root.drop_down.open(self)
        Button:
            id: btn_ddID2
            text: 'Gym Access'
            on_release: root.drop_down.open(self)
        Button:
            text: 'Training Level'
            on_release: root.drop_down.open(self)

1 Ответ

0 голосов
/ 15 ноября 2018
  class getFitScreen(Screen):
    def __init__(self, *args, **kwargs):
        super(getFitScreen, self).__init__(*args, **kwargs)
        self.dropdown = DropDown()
        self.dropdown1 = DropDown()
        self.dropdown2= DropDown()
        time = ['15-30mins', '30-60mins', '60-90mins', '90-120mins']
        level = [1, 2, 3]
        access = [True, False]

        for times in time:
            btn = Button(text='%r' % times, size_hint_y=None, height=30)
            btn.bind(on_release=lambda btn: self.dropdown.select(btn.text))
            self.dropdown.add_widget(btn)
        mainbutton = Button(text='Time Available', size_hint=(1, 1))
        mainbutton.bind(on_release=self.dropdown.open)
        self.dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x))

        for levels in level:
            btn1 = Button(text='%r' % levels, size_hint_y=None, height=30)
            btn1.bind(on_release=lambda btn1: self.dropdown1.select(btn1.text))
            self.dropdown1.add_widget(btn1)
        mainbutton1 = Button(text='Training Level', size_hint=(1, 1))
        mainbutton1.bind(on_release=self.dropdown1.open)
        self.dropdown1.bind(on_select=lambda instance, x: setattr(mainbutton1, 'text', x))

        for bool in access:
            btn2 = Button(text = '%r' % bool, size_hint_y=None,height=30)
            btn2.bind(on_release = lambda btn2 : self.dropdown2.select(btn2.text))
            self.dropdown2.add_widget(btn2)
        mainbutton2 = Button(text = 'Gym Access',size_hint=(1,1))
        mainbutton2.bind(on_release=self.dropdown2.open)
        self.dropdown2.bind(on_select=lambda instance, x: setattr(mainbutton2,'text', x))

Итак, это изменение файла .py выше.Я пропустил остальную часть кода, только код для экрана, в который я пытаюсь поместить выпадающие меню.

<getFitScreen>:
id: getFitScreen
top_layout: topLayoutID
dd_btn: btn_ddID 
BoxLayout:
    id: topLayoutID
    size_hint: 1, .05
    pos_hint: {'x': 0, 'y': .95}
    Button:
        id: btn_ddID
        text: 'Time Availablity'
        on_release: root.dropdown.open(self)
    Button:
        id: btn2_ddID2
        text: 'Training Level'
        on_release: root.dropdown1.open(self)
    Button:
        id: btn3_ddID3
        text: 'Gym Access'
        on_release: root.dropdown2.open(self)

Тогда единственное изменение, которое я внес в файл .kv, было в самомконец, соответствующий экрану, в который я хотел внести коррективы.В основном мне просто нужно было изменить пару имен переменных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...