简体   繁体   中英

How do I build by dropdown menu on a specific screen in Kivy?

I'm trying to get my program to display the dropdown menu on a specific screen (screen two). I've tried to do this by defining the function that builds the dropdown menu under Class ScreenTwo. However, when I run the program, the dropdown menu isn't displayed at all (black box is a button, not a glitch).

Dropdown menu isn't displayed

I tried to work around this by building the dropdown menu using the statement ScreenTwo.drop_down(self) under

def build(self):
    Clock.schedule_once(self.blink_animation)
    return ScreenTwo.drop_down(self)
    return screen_manager

However, now only the dropdown menu shows, and none of the other screens or widgets are displayed. ScreenOne isn't displayed either, only the dropdown menu. I understand it's because the drop_down function is returned first before screen_manager .

Only dropdown menu is displayed

I also tried making the dropdown menu solely in the.kv language, however, class ScreenOne(Screen) did not permit that (or so I assume, I'm very new to Kivy). I've kept my whole code below, and highlighted the relevant bits.

    import kivy
kivy.require('1.11.1')

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.config import Config
from kivy.animation import Animation
from kivy.clock import Clock
from datetime import datetime
from datetime import timedelta
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.base import runTouchApp
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout




# You can create your kv code in the Python file
Builder.load_string("""
<ScreenOne>:
    FloatLayout:
        orientation: 'horizontal'
        canvas:
            Rectangle:
                source: 'back1.jpg'
                size: self.size
                pos: self.pos
    BoxLayout:
        Button:
            background_color: 0, 0, 0, 0
            on_press:
                # You can define the duration of the change
                # and the direction of the slide
                root.manager.transition.direction = 'up'
                root.manager.transition.duration = 1
                root.manager.current = 'screen_two'

    BoxLayout: 
        Label:
            id: blinky
            text: "Click Anywhere To Continue"
            font_size: '20sp'
            font_name: "Raleway-Regular"
            size_hint: (1.0, 0)
            alpha: 1
            color: (1, 1, 1, self.alpha)


<ScreenTwo>:
    FloatLayout:
        orientation: 'horizontal'
        canvas:
            Rectangle:
                source: 'back2.jpg'
                size: self.size
                pos: self.pos
        Label:
            id: white_box
            size: (500,500)
            alpha: 1
            bcolor: (1, 1, 1, self.alpha)
        Button:
            background_color: 0, 0, 0, 1
            size: (400, 130)
            size_hint: (None, None)
            pos_hint: {'right': 0.6, 'center_y': 0.30}
            on_press:
                root.time_now()
                root.manager.current = 'screen_three'

<ScreenThree>:
    BoxLayout:
        Button:
            background_color: 1, 0, 0, 1
            on_press:
                # You can define the duration of the change
                # and the direction of the slide
                root.manager.current = 'screen_two'
""")

# Create a class for all screens in which you can include
# helpful methods specific to that screen

Config.set('graphics', 'resizable', '0') #0 being off 1 being on as in true/false
Config.set('graphics', 'width', '960')
Config.set('graphics', 'height', '720')

class ScreenOne(Screen):
    pass

class ScreenTwo(Screen):
    def time_now(self):
        global now, month_now, date_now, day_now, hour_now, minute_now, time_now
        now = datetime.now()
        print(now)

        month_now = int(now.strftime("%m"))  # month in int
        print("month:", month_now)

        date_now = int(now.strftime("%d"))  # date in int
        print("date:", date_now)

        day_now = now.strftime("%A")  # day in str
        print("day of the week:", day_now)

        hour_now = int(now.strftime("%H")) * 100
        minute_now = int(now.strftime("%M"))
        time_now = hour_now + minute_now  # day in str in 24 hour format
        print("time:", time_now)
    def check_open(day_now, opening_days, time_now, opening_time):
        global isopen
        opening_days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Saturday"]
        opening_time = [800, 2200]
        isopen = False
        if day_now in opening_days and time_now >= opening_time[0] and time_now <= opening_time[1]:
            isopen = True
            print("Is the store open? ", isopen)
            return isopen
        else:
            print("Is the store open? ", isopen)
            return

This is the actual dropdown menu itself

def drop_down(self): global days days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] global layout layout = GridLayout(cols=4, spacing=10, size_hint_y=None) dropdown1 = DropDown() for index in range(7): btn1 = Button(text=days[index], size_hint_y=None, height=44) btn1.bind(on_release=lambda btn1: dropdown1.select(btn1.text)) dropdown1.add_widget(btn1) daybutton = Button(text='Day', size_hint=(None, None)) daybutton.bind(on_release=dropdown1.open) dropdown1.bind(on_select=lambda instance, x: setattr(daybutton, 'text', x)) layout.add_widget(daybutton) dropdown = DropDown() for index in range(24): # When adding widgets, we need to specify the height manually # (disabling the size_hint_y) so the dropdown can calculate # the area it needs. btn = Button(text='%d' % index, size_hint_y=None, height=44) # for each button, attach a callback that will call the select() method # on the dropdown. We'll pass the text of the button as the data of the # selection. btn.bind(on_release=lambda btn: dropdown.select(btn.text)) # then add the button inside the dropdown dropdown.add_widget(btn) # create a big main button mainbutton = Button(text='Hour', size_hint=(None, None)) # show the dropdown menu when the main button is released # note: all the bind() calls pass the instance of the caller (here, the # mainbutton instance) as the first argument of the callback (here, # dropdown.open.). mainbutton.bind(on_release=dropdown.open) # one last thing, listen for the selection in the dropdown list and # assign the data to the button text. dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x)) layout.add_widget(mainbutton) dropdown2 = DropDown() for index in range(60): btn2 = Button(text='%d' % index, size_hint_y=None, height=44) btn2.bind(on_release=lambda btn2: dropdown2.select(btn2.text)) dropdown2.add_widget(btn2) minutebutton = Button(text='Minute', size_hint=(None, None)) minutebutton.bind(on_release=dropdown2.open) dropdown2.bind(on_select=lambda instance, x: setattr(minutebutton, 'text', x)) layout.add_widget(minutebutton) def submitted(self): global day_now global hour_now global minute_now global time_now day_now = daybutton.text hour_now = int(mainbutton.text) minute_now = int(minutebutton.text) time_now = hour_now + minute_now check_open(day_now, opening_days, time_now, opening_time) return day_now, hour_now, minute_now, time_now # submitbutton = Button(text='Submit', size_hint=(None, None)) # submitbutton.bind(on_release=submitbutton.submitted) # layout.add_widget(submitbutton) return layout

pass

class ScreenThree(Screen):
    pass



# The ScreenManager controls moving between screens
screen_manager = ScreenManager()

# Add the screens to the manager and then supply a name
# that is used to switch screens
screen_manager.add_widget(ScreenOne(name="screen_one"))
screen_manager.add_widget(ScreenTwo(name="screen_two"))
screen_manager.add_widget(ScreenThree(name="screen_three"))

class KivyTut2App(App):
    def blink_animation(self, dt):
        anim = Animation(alpha=0, duration=1) + Animation(alpha=1, duration=1)
        anim.repeat = True
        anim.start(screen_manager.get_screen('screen_one').ids.blinky)
    def build(self):
        Clock.schedule_once(self.blink_animation)

I try to build the dropdown menu here

 return ScreenTwo.drop_down(self)
return screen_manager

sample_app = KivyTut2App()
sample_app.run()

A few changes to get your DropDown to work.

  • Change your return in the build() method to return screen_manager and remove the other return from that method. A method can only return once.
  • Rename your drop_down method to def on_enter(self, *args): . This will get the method called automatically when ScreenTwo is displayed.
  • Replace the return layout statement at the end of the above method with self.add_widget(layout) . This will add the DropDown to ScreenTwo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM