0

我正在使用 Kivy 和 Kivymd。我在class Admin和之间传递变量时遇到问题class EditArticle。我需要my_string从管理员传递到 EditArticle。我正在尝试这样做,但得到一个空字符串。所以,在class Admin我有my_string. 然后,在我设置值“一些文本”的方法edit_article中。然后我试图用 . 但它一直是空的。我真的想不通。class Adminmy_stringeditclass EditArticle

  1. 如果您运行我的代码,您将单击顶部菜单admin
  2. 然后点击任意mdchip
  3. 然后单击对话框窗口中的 etit 按钮。
  4. 然后点击按钮获取my_string(但它总是空的)。

这是我的 App.py

from kivy.clock import Clock
from kivymd.app import MDApp
from kivy.properties import StringProperty, NumericProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.card import MDCard
from kivymd.uix.chip import MDChip
from kivy.core.window import Window
Window.size = (600, 853)
from kivymd.uix.menu import MDDropdownMenu
from kivymd.theming import ThemableBehavior
from kivymd.uix.behaviors import RectangularElevationBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog

class WindowManager(ScreenManager):
    pass

class AdminFooter(ThemableBehavior, RectangularElevationBehavior, MDBoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.md_bg_color = self.theme_cls.primary_color

class ToolbarBack(ThemableBehavior, RectangularElevationBehavior, MDBoxLayout):
    pass

class CustomToolbar(ThemableBehavior, RectangularElevationBehavior, MDBoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.md_bg_color = self.theme_cls.primary_color

        Clock.schedule_once(self.create_menu, 1)

    def create_menu(self, i):
        self.items = ['admin', 'settings']
        menu_items = [{"text":  f"{i}"} for i in self.items]
        self.menu = MDDropdownMenu(
            caller=self.ids.button_2, items=menu_items, width_mult=4, callback=self.get_item
        )

    def get_item(self, instance):
        self.menu.dismiss()
        App.get_running_app().window_manager.current = instance.text

class Content(BoxLayout):
    pass

class Admin(Screen):

    dialog_get_article = None

    my_string = StringProperty() # My string

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def get_article(self, instance,*args): 
        self.dialog_get_article = MDDialog(
            title="Click the EDIT",
            buttons=[
                MDFlatButton(
                    text="EDIT",
                    on_release = self.edit_article
                ),
            ],
        )
        self.dialog_get_article.open()

    def edit_article(self, instance):
        self.my_string = 'some text' # set value
        App.get_running_app().window_manager.current = 'edit-article'
        self.dialog_get_article.dismiss()

    def on_enter(self, *args):
        data = [
            {'id': 1, 'title': 'Arcicle 1', 'body': 'body of Article 1'},
            {'id': 2, 'title': 'Arcicle 2', 'body': 'body of Article 2'},
            {'id': 3, 'title': 'Arcicle 3', 'body': 'body of Article 3'}
        ]
        for x in data:
            chip = BlogChip(id=x.get('id'), title=x.get('title'), body=x.get('body'))
            self.ids.box.add_widget(chip)

class EditArticle(Screen):

    var = StringProperty()

    def edit(self, instance):
        print(self.var, ' << it is goingt to be <my_string> from Admin')

class UserSettings(Screen):
    pass

class BlogChip(MDChip):

    get_admin = Admin()

    id = NumericProperty()
    title = StringProperty()
    body = StringProperty()

class BlogCard(MDCard):
    pass

class Detail(Screen):
    pass

class ResultSearch(Screen):
    pass

class Container(Screen):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Clock.schedule_once(self.create_cards)

    def create_cards(self, i):
        pass

class App(MDApp):

    def callback(self):
        self.window_manager.current = 'container'

    def build(self):
        self.theme_cls.primary_palette = 'Indigo'
        self.window_manager = WindowManager()
        return self.window_manager

App().run()

我的应用.kv

 <WindowManager>
    Container:
        id: scr_1
        name: 'container'
    Detail:
        id: scr_2
        name: 'detail'

    Admin:
        id: scr_3
        name: 'admin'
    EditArticle:
        id: scr_4
        name: 'edit-article'
        var: scr_3.my_string # <---------

    ResultSearch:
        id: scr_5
        name: 'result-search'
    UserSettings:
        id: scr_6
        name: 'settings'

<Admin>:
    BoxLayout:
        id: boxlayout_1
        orientation: 'vertical'

        MDToolbar:
            pos_hint: {'top': 1}
            title: 'Admin Blog'
            left_action_items: [["arrow-left", lambda x: app.callback()]]

        ScrollView:
            MDStackLayout:
                adaptive_height: True
                padding: 10
                spacing: dp(5)
                id: box

<EditArticle>
    MDToolbar:
        title: 'Admin Blog'
    MDLabel:
        text: str(root.var)
    MDRaisedButton:
        text: 'click me to see a variable in console'
        pos_hint: {'center_x': .5, 'center_y': .5}
        on_release: root.edit(root)

<MyToolbar@CustomToolbar>:
    size_hint_y: None
    height: self.theme_cls.standard_increment
    padding: "25dp"
    spacing: "12dp"

    MDLabel:
        id: label
        text: 'Blog'
        font_style: 'H6'
        theme_text_color: "Custom"
        text_color: 1,1,1,1

    Widget:

    MDIconButton:
        id: button_2
        icon: "dots-vertical"
        pos_hint: {"center_y": .5}
        theme_text_color: "Custom"
        text_color: 1,1,1,1
        on_release: root.menu.open()

<Container>
    BoxLayout:
        orientation: 'vertical'
        MyToolbar:
        MDLabel:
            text: 'Go To menu (dot-vertical/admin'
            halign: 'center'

<BlogCard>

<Detail>:

<BlogChip>
    label: root.title
    icon: ''
    callback: root.get_admin.get_article
4

3 回答 3

2

根本原因:

在您的应用程序中,有两个实例class Admin化实例。

WindowManager()第一个实例是在方法中实例化根时在 kv 文件中实例化的build

片段:

<WindowManager>:
    ...

    Admin:
        id: scr_3
        name: 'admin'
    ...

第二个实例在class BlogChip.

片段:

class BlogChip(MDChip):
    get_admin = Admin()
    ...

类属性my_string在 的第二个实例中更新class Admin。但是屏幕正在引用由根实例化的实例。因此,应用程序显示空字符串。

解决方案:

该解决方案需要更改 kv 和 python 文件。

.kv 文件:

替换 callback: root.get_admin.get_articlecallback: app.root.ids.scr_3.get_article

片段:

<BlogChip>
    label: root.title
    icon: ''
    callback: app.root.ids.scr_3.get_article

蟒蛇文件:

  1. 删除get_admin = Admin()_class BlogChip(MDChip):

片段:

class BlogChip(MDChip):
    id = NumericProperty()
    title = StringProperty()
    body = StringProperty()
  1. 在方法中,edit()初始化类属性,var

片段:

class EditArticle(Screen):
    var = StringProperty()

    def edit(self, instance):
        # Each screen has by default a property manager that 
        # gives you the instance of the ScreenManager used.
        self.var = self.manager.ids.scr_3.my_string
        print(self.var, ' << it is going to be <my_string> from Admin')

输出:

在此处输入图像描述

于 2020-07-11T22:08:58.453 回答
0

我真的不明白你在你的代码中做什么?

你为什么不直接看你的Admin.my_string内部EditArticle class

如果这不起作用,您是否尝试getter为您的my_string属性创建一个?
我很抱歉,我不知道如何StringProperty工作......但是你不能在下面做类似的事情Agent class吗?

def get_my_string():
    return my_string.value()

然后你就打电话给Agent.get_my_string()你的EditArticle班级。

于 2020-07-11T14:42:28.483 回答
0

这是我的问题的解决方案。我必须添加EditArticle.my_string = self.my_string这样的class Admin内容:

def edit_article(self, instance):
    EditArticle.my_string = self.my_string
    App.get_running_app().window_manager.current = 'edit-article'
    self.dialog_get_article.dismiss()

在这之后我可以把它放进去class EditArticle()

于 2020-07-11T19:59:48.053 回答