Как добавить виджет в StackLayout внутри ScrollView внутри FloatLayout? - PullRequest
0 голосов
/ 06 февраля 2019

Довольно новичок в kivy и только имеет высшее образование на python и застрял на этом уже неделю.Мне нужна система, в которой я могу добавлять и удалять кнопки в StackLayout, как мне это сделать?

Я могу добавлять и удалять кнопки, теперь мне просто нужно выяснить, как расположить их в нужном месте.площадь.

Я понимаю, что этот вопрос немного похож на кластер ***, и я глубоко в этом разбирался, но я решил, что лучше всего научиться погружаться прямо в него.

код питона:

# import kivy & functions/widgets.
import kivy
from kivy.app import App
from kivy.uix.button import Button

# import kivy layouts.
from kivy.uix.floatlayout import FloatLayout

# Specify version of kivy needed.
kivy.require("1.10.1")

# define buttons and widgets
testButton = Button(width=177, height=254, size_hint=(None, None), background_normal="pics/32864.jpg")


class Page(FloatLayout):
    def __init__(self):
        super().__init__()

    def add_button(self):
        Page.add_widget(self, widget=testButton)


class YuGiOhApp(App):
    pass


YuGiOhApp().run()

мой код .kv:

#:kivy 1.10.1

<TestButton@Button>:
    width: 177
    height: 254
    size_hint: None, None
    background_normal: "pics/32864.jpg"

FloatLayout:

    Button:
        size_hint: 0.20, 0.10
        pos_hint: {"x": 0.60, "top": 1}
        text: "Search"
        on_press: root.add_button()

    Button:
        size_hint: 0.20, 0.10
        pos_hint: {"x": 0.80, "top": 1}
        text: "collection"

    TextInput:
        multiline: False
        font_size: 48
        size_hint: 0.60, 0.10
        pos_hint: {"x": 0, "top": 1}

    ScrollView:
        size_hint: 0.60, 0.90

        StackLayout:
            orientation: "lr-tb"
            pos_hint: {"x": 0, "top": 0.88}
            size_hint: 1, None

            height: self.minimum_height

            padding: 5
            spacing: 5

            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:

Редактировать 4: Ошибка «AttributeError: у объекта« FloatLayout »нет атрибута add_button» при попыткезапустить функцию add_button (), когда нажата кнопка «поиск»

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Есть несколько проблем с вашим кодом.

Во-первых, ваш kv относится к FloatLayout, когда кажется, что вы действительно хотите сослаться на свой класс Page.(Вы ссылаетесь на root.add_button(), но этот метод относится к классу Page).

Во-вторых, ваш testbutton является единичным экземпляром TestButton, поэтому при втором нажатии на Search кнопка, вы получите сообщение об ошибке, если у этой кнопки уже есть родитель.Поэтому я создал класс TestButton в коде Python и удалил правило <TestButton@Button> из kv.

Вот что, я думаю, вы хотите для своего кода:

# import kivy & functions/widgets.
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button

# import kivy layouts.
from kivy.uix.floatlayout import FloatLayout

# Specify version of kivy needed.
kivy.require("1.10.1")

# define buttons and widgets
class TestButton(Button):
    def __init__(self, **kwargs):
        super(TestButton, self).__init__(**kwargs)
        self.width = 177
        self.height = 254
        self.size_hint = (None, None)
        self.background_normal = "pics/32864.jpg"


class Page(FloatLayout):
    def __init__(self):
        super().__init__()

    def add_button(self):
        self.ids.stack.add_widget(TestButton())



class YuGiOhApp(App):
    def build(self):
        return Page()


YuGiOhApp().run()

И добавьте id для вашего StackLayout в kv:

#:kivy 1.10.1
<Page>:

    Button:
        size_hint: 0.20, 0.10
        pos_hint: {"x": 0.60, "top": 1}
        text: "Search"
        on_press: root.add_button()

    Button:
        size_hint: 0.20, 0.10
        pos_hint: {"x": 0.80, "top": 1}
        text: "collection"

    TextInput:
        multiline: False
        font_size: 48
        size_hint: 0.60, 0.10
        pos_hint: {"x": 0, "top": 1}

    ScrollView:
        size_hint: 0.60, 0.90

        StackLayout:
            id: stack
            orientation: "lr-tb"
            pos_hint: {"x": 0, "top": 0.88}
            size_hint: 1, None

            height: self.minimum_height

            padding: 5
            spacing: 5

            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:
            TestButton:

Новый метод add_button() ссылается на новый stack id для доступа к StackLayout и создаетновый TestButton каждый раз, когда он вызывается.

0 голосов
/ 06 февраля 2019

Вы можете присвоить своему StackLayout виджету уникальный id.

StackLayout:
    id: your_stacklayout_id
    ...

Затем для доступа к виджету StackLayout вы можете использовать его id внутри виджета root.

#: import Factory kivy.factory.Factory

FloatLayout:

    ...

    Button:
        text: "Add new Button"
        on_press: root.ids["your_stacklayout_id"].add_widget(Factory.TestButton())

    ...

Вот базовый пример:

main.py

from kivy.app import App
from kivy.uix.boxlayout import *
from kivy.uix.button import *

class Main(BoxLayout):
    pass

class TestApp(App):
    def build(self):
        return Main()

TestApp().run()

test.kv

#: import Factory kivy.factory.Factory

<MyButton@Button>:
    text: "Added Button"

<Main>:
    BoxLayout:
        orientation: "vertical"

        Button:
            text: "Add New Button"
            on_press: root.ids["my_boxlayout_id"].add_widget(Factory.MyButton())

        BoxLayout:
            id: my_boxlayout_id
            orientation: "vertical"
...