簡體   English   中英

使用On_Press事件來更改沒有KV語言的屏幕以動態創建按鈕

[英]Use On_Press Event to Change Screen without KV Language for Dynamically Created Buttons

題:

在不使用KV語言的情況下,如何使用On-Press事件更改python中動態創建的按鈕的屏幕?

目標:

通過單擊動態創建的按鈕,可以導航到新屏幕,

[無需在Kivy中創建按鈕,並且仍然可以在Python和Kivy中同時使用Screenmanager(不確定在整個程序中是否必須使用Python還是Kivy?)

我已經嘗試過的事情:

  1. 使用button_share.bind(on_press = self.changer) ,然后這樣做:

def changer(self,*args):
    ScreenManager()
    screenmanager.current = 'MainScreen'

但是我收到錯誤ScreenManagerException: No Screen with name "MainScreen".

懷疑:

我認為這是因為我正在創建ScreenManager的新實例,而不是引用現有實例。 為了解決這個問題,我考慮在App類中實例化Screenmanager(),然后在我的按鈕def changer(self, *args)方法中引用該實例化,但是如果它與我實際上用於所有對象的ScreenManager不同,那將是無用的我的屏幕。 這些都是用KV語言定義的。 如果不付出很大的努力,我將無法將它們全部切換。

  1. 使用:

button_share.bind(on_press=partial(app.sm.setter('current'), (app.sm, "MainScreen")))`

但是我得到的錯誤是ValueError: ScreenManager.current accept only str

下面是一個完全可運行的示例:

注意:在此示例中,我要單擊“繼續編輯”按鈕,然后單擊“測試1”,“測試2”或“測試3”按鈕,然后將其帶到另一個屏幕。

Python代碼:

from kivy.app import App
# kivy.require("1.10.0")
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.uix.widget import Widget
#from kivy.base import runTouchApp
from kivy.properties import StringProperty, ObjectProperty, NumericProperty
from functools import partial

class ScrollableLabelDataEntryInstructions(BoxLayout):
    pass

class NewGarageScreen(Screen):
    pass

class ContinueEditingScreen(Screen):
    pass

class GarageNameBoxLayout(BoxLayout):
    box_share2 = ObjectProperty()
    sm = ScreenManager()

    def __init__(self, **kwargs):
        super(GarageNameBoxLayout, self).__init__(**kwargs)
        self.orientation = "vertical"
        Clock.schedule_interval(self.create_button, 5)

    def create_button(self, *args):
        self.box_share2.clear_widgets()
        app = App.get_running_app()
        #put GarageNameStartList data into app class, then pull from it in this class
        top_button_share = 1.1
        color = (.4, .4, .4, 1)
        for i in range(len(app.GarageNameStartList)):
            top_button_share -= .4
            id_ = app.GarageNameStartList[i]

            button_share = Button(background_normal='',
                                  background_color = color,
                                  id = id_,
                                  pos_hint = {"x": 0, "top": top_button_share},
                                  size_hint_y = None,
                                  height = 60,
                                  font_size = 30,
                                  text = app.GarageNameStartList[i])
            button_share.bind(on_press = self.changer)
            #button_share.bind(on_press=partial(app.sm.setter('current'), (app.sm, "MainScreen")))
            self.box_share2.add_widget(button_share)

    def changer(self,*args):
        ScreenManager()
        #app = App.get_running_app()
        screenmanager.current = 'MainScreen'

class BackHomeWidget(Widget):
    pass

class MainScreen(Screen):
    pass

class AnotherScreen(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass

presentation = Builder.load_file("example_on_press.kv")

class MainApp(App):
    GarageNameStartList = ["Test1", "Test2", "Test3"]

    def Update_GarageNameStartList(self, *args):
        self.GarageNameStartList = ["Test1", "Test2", "Test3"]   


    def build(self):
        return presentation

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

驗證碼:

#: import FadeTransition kivy.uix.screenmanager.FadeTransition

ScreenManagement:
    transition: FadeTransition()
    MainScreen:
    AnotherScreen:
    NewGarageScreen:
    ContinueEditingScreen:

<SmallNavButton@Button>:    
    font_size: 32
    size: 125, 50    
    color: 0,1,0,1

<MedButton@Button>:
    font_size: 30
    size_hint: 0.25, 0.1
    color: 0,1,0,1

<BackHomeWidget>:
    SmallNavButton:
        on_release: app.root.current = "main"
        text: "Home"
        pos: root.x, root.top - self.height

<MainScreen>:
    name: "main"
    FloatLayout: 
        MedButton:
            on_release: app.root.current = "edit"
            text: "Edit"
            pos_hint: {"x":0.3728, "top": 0.4}

<AnotherScreen>:
    name: "edit"
    BackHomeWidget:
        SmallNavButton:
            on_release: app.root.current = "main"
            text: "Back"
            pos: root.x, root.top - (2.25*(self.height))
    FloatLayout:
        MedButton:
            on_release: app.root.current = "continueediting"
            text: "Continue Editing"
            pos_hint: {"x":0.25, "top": 0.6} 
        MedButton:
            on_release: app.root.current = "newgarage"
            text: "Create New"
            pos_hint: {"x":0.3728, "top": 0.4}

<NewGarageScreen>:
    name: "newgarage"
    BackHomeWidget:
        SmallNavButton:
            on_release: app.root.current = "edit"
            text: "Back"
            pos: root.x, root.top - (2.25*(self.height))
    FloatLayout:
        MedButton:
            text: "1. Groundfloor"
            pos_hint: {"x":0, "top": 0.6}


<GarageNameBoxLayout>:
    box_share2: box_share2
    ScrollView:
        GridLayout:
            id: box_share2
            cols: 1
            size_hint_y: None
            size_hint_x: 0.5
            spacing: 5
            padding: 130
            height: self.minimum_height
            canvas:
                Color: 
                    rgb: 0, 0, 0
                Rectangle:
                    pos: self.pos
                    size: self.size         

<ContinueEditingScreen>:
    name: "continueediting"
    GarageNameBoxLayout:
    BackHomeWidget:
        SmallNavButton:
            on_release: app.root.current = "edit"
            text: "Back"
            pos: root.x, root.top - (2.25*(self.height))

您的代碼可以在以下方面進行改進:

  • 您不必在.py中創建box_share2,因為您是在.kv中創建它的

  • 當您使用sm = ScreenManager()您將創建另一個不同於原始ScreenManager ,這不是必需的。

  • 不必使用rangelen ,使代碼的可讀性降低,您只需進行迭代即可。

  • 如果我們查看.kv的結構,我們會看到演示對象是ScreenManager因此可以通過app.root獲取它。

使用上面的代碼,解決方案是:

[...]

class GarageNameBoxLayout(BoxLayout):
    def __init__(self, **kwargs):
        super(GarageNameBoxLayout, self).__init__(**kwargs)
        self.orientation = "vertical"
        Clock.schedule_interval(self.create_button, 5)

    def create_button(self, *args):
        self.box_share2.clear_widgets()
        app = App.get_running_app()
        sm = app.root

        #put GarageNameStartList data into app class, then pull from it in this class
        top_button_share = 1.1
        color = (.4, .4, .4, 1)
        for text in app.GarageNameStartList:
            top_button_share -= .4
            id_ = text
            button_share = Button(background_normal='',
                                  background_color = color,
                                  id = id_,
                                  pos_hint = {"x": 0, "top": top_button_share},
                                  size_hint_y = None,
                                  height = 60,
                                  font_size = 30,
                                  text = text)
            button_share.bind(on_press=lambda *args: setattr(sm, 'current', "main"))
            self.box_share2.add_widget(button_share)

[...]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM