python - 将 ScreeManager 与 Kivy- 按钮布局一起使用时的问题不再有效

标签 python python-3.x user-interface kivy kivy-language

所以我在尝试使用屏幕管理器时遇到了问题。因为我必须创建我的屏幕类现在是 (Screen) 而不是 (GridLayout) 才能完全使用屏幕管理器,例如,按钮/布局管理不能再在 python 中控制了吗?它曾经在屏幕上布置 5 列和 3 行,总共 15 个按钮。现在它只显示一个大的(屏幕)而不是网格布局。

class LandingScreen(Screen):
def build(self):
    return presentation
def __init__(self, **kwargs):
    super(LandingScreen, self).__init__(**kwargs)
    self.cols = 5
    self.buttons = []  # add references to all buttons here

    # Loop to make 20 different buttons on screen
    for x in range(15):
        self.buttons.append(Button(text='button ' + str(x)))  # make a reference to the button before adding it in
        self.add_widget(self.buttons[x])
        self.buttons[x].background_normal = 'YOUTUBE.png'

此处的按钮和列设置用于使用此循环创建 3 行,每行 5 个按钮,但由于我将 (Screen) 添加到类而不是 (GridLayout),所以不会。我宁愿不在 .kv 文件中创建所有按钮,因为我认为在 .py 中更容易管理并且对我来说更有意义。

这是我的 .kv 文件:

<GridLayout>:
    cols: 5
    height: 480
    width: 800
    spacing: 25, 20
    padding: 25,25

<MyScreenManager>:
    LandingScreen:
    InputScreen:

<InputScreen>:
    AnchorLayout:

<LandingScreen>:
    GridLayout:
        cols: 5
        height: 480
        width: 800
        spacing: 25, 20
        padding: 25,25

这显然是多余的,因为我试图弄清楚如何让所有 15 个按钮再次显示,而不仅仅是一个。

谢谢!

最佳答案

您想将按钮添加到 Screen 内的 GridLayout,而不是直接添加到 Screen。为此,请使用 id 来引用 GridLayout

但是,您不能在 __init__ 方法中使用 id,因为在完全初始化相应的小部件之前,不会应用 kv 文件中定义的规则。 Ryan Pi 在这个问题中正确提供了解决方案:

Why can't I access the Screen.ids?

另一方面,要稍后更改屏幕,您必须在您的屏幕中定义 name 属性。

您的代码应该是:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.clock import Clock


kv_text='''\

<MyScreenManager>:
    LandingScreen:
    InputScreen:

<InputScreen@Screen>:
    name: 'input_sc'
    AnchorLayout:
        id: anchor_1

<LandingScreen@Screen>:
    name: 'landing_sc'
    GridLayout:
        id: grid_1
        cols: 5
        height: 480
        width: 800
        spacing: 25, 20
        padding: 25,25
'''

class MyScreenManager(ScreenManager):
    pass


class LandingScreen(Screen):
    def __init__(self, **kwargs):
        super(LandingScreen, self).__init__(**kwargs)
        self.buttons = [] # add references to all buttons here
        Clock.schedule_once(self._finish_init)

    def _finish_init(self, dt):
        self.ids.grid_1.cols = 5

        # Loop to make 20 different buttons on screen
        for x in range(15):
            self.buttons.append(Button(text='button {}'.format(x)))
            self.ids.grid_1.add_widget(self.buttons[x])
            self.buttons[x].background_normal = 'YOUTUBE.png'

class MyKivyApp(App):
    def build(self):
        return MyScreenManager()

def main():
    Builder.load_string(kv_text)
    app = MyKivyApp()
    app.run()

if __name__ == '__main__':
    main()

如果你想使用 Properties 而不是 ids 方法(参见 documentation ),你应该这样做:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.properties import ObjectProperty


kv_text='''\

<MyScreenManager>:
    LandingScreen:
    InputScreen:

<InputScreen@Screen>:
    name: 'input_sc'
    AnchorLayout:
        id: anchor_1

<LandingScreen@Screen>:
    name: 'landing_sc'
    grid_1: grid_1
    GridLayout:
        id: grid_1
        cols: 5
        height: 480
        width: 800
        spacing: 25, 20
        padding: 25,25
'''

class MyScreenManager(ScreenManager):
    pass


class LandingScreen(Screen):

    grid_1 = ObjectProperty(None)    #<<<< Propertie

    def __init__(self, **kwargs):
        super(LandingScreen, self).__init__(**kwargs)
        self.buttons = [] # add references to all buttons here
        Clock.schedule_once(self._finish_init)

    def _finish_init(self, dt):
        self.grid_1.cols = 5
        # Loop to make 20 different buttons on screen
        for x in range(15):
            self.buttons.append(Button(text='button{}'.format(x)))
            self.grid_1.add_widget(self.buttons[x])
            self.buttons[x].background_normal = 'star.png'

class MyKivyApp(App):
    def build(self):
        return MyScreenManager()

def main():
    Builder.load_string(kv_text)
    app = MyKivyApp()
    app.run()

if __name__ == '__main__':
    main()

关于python - 将 ScreeManager 与 Kivy- 按钮布局一起使用时的问题不再有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44837609/

相关文章:

python-3.x - 如何转换 wav 文件 -> bytes-like 对象?

user-interface - CloverETL/热情/全局环境基金

python - Dragonfly 的模态命令

python - Django 表单,重写 init,变量范围

python - 使用 py.test 在 Python 中测试正则表达式

android - 如何制作不是图像的Android xml自定义ui元素

c++ - 如何在大型机中显示 CFormView?

python - Windows 10 上的 Notepad++ 显示空白错误

python - 如何在 tkinter 框架中嵌入 vlc 实例

python - 为什么print语句不是pythonic?