如何将弹出窗口上的属性更改为与打开该弹出窗口的按钮的属性相同?

2024-04-29 16:47:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我的项目是纸牌游戏。每张卡片也是一个按钮。当你点击游戏中的一张牌时,弹出窗口会显示一张牌的图像、一个可滚动的牌文本标签和各种按钮。你知道吗

PopUp

我目前的问题是试图改变弹出窗口中的图像和文本,以匹配实际的卡按钮信息。我目前有能力改变显示的信息,但只是作为它的最新定义。据我所知,这是因为我重新定义了class属性,而不是class属性的实例。你知道吗

我尝试过在Card(Button Image)文件中执行def_uuuinit_uuuu(self,parameters):但是,每当我尝试执行PlayMatWidget的draw方法时,它都会崩溃。你知道吗

我认为这可能与Kivy对象属性有关,但我不完全确定如何准确地使用它们(主要是因为按钮不是在运行时创建的)

谢谢你的阅读!你知道吗

Python文件:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty
from kivy.lang import Builder
import random

Builder.load_string('''
<ScrollableLabel>:
    Label:
        size_hint_y: None
        height: self.texture_size[1]
        text_size: self.width, None
        text: root.text
''')


class ScrollableLabel(ScrollView):
    text = StringProperty('')


# Visual Representation of a Card or Deck
class ImageButton(ButtonBehavior, Image):
    pass


class CardBackend:
    def __init__(self, name, card_art, effect_one):
        self.name = name
        self.card_art = card_art
        self.effect = effect_one


class Card(ImageButton):
    # Defining the Popup Window
    main_pop = Popup()
    main_pop.title = 'Inspect Card'
    main_pop.title_align = 'center'
    main_pop.size_hint = None, None
    main_pop.size = 400, 400
    main_pop.auto_dismiss = False
    main_pop.opacity = 0.8

    # Variables or Variables to Be
    card_text = 'ABCDEFGHIJK1234567890' * 100
    card_art = Image(source='test.png', size_hint=(.9, .85), pos_hint={'x': -0.18, 'y': .125})

    # Primary Child Widget
    main_box = FloatLayout()

    # Buttons
    play_button = Button(text='Play', size_hint=(0.32, 0.1), pos_hint={'x': 0.01, 'y': 0.0})
    discard_button = Button(text='Discard', size_hint=(0.32, 0.1), pos_hint={'x': 0.34, 'y': 0.0})
    close_button = Button(text='Close', size_hint=(0.32, 0.1), pos_hint={'x': 0.67, 'y': 0.0})
    close_button.bind(on_press=main_pop.dismiss)

    # Scrolling Card Text Viewer
    card_info = ScrollableLabel(text=card_text, size_hint=(0.45, .8), pos_hint={'x': .55, 'y': .15})

    # Building main_pop.content
    main_box.add_widget(play_button)
    main_box.add_widget(discard_button)
    main_box.add_widget(close_button)
    main_box.add_widget(card_info)
    main_box.add_widget(card_art)
    main_pop.content = main_box


class PlayMatWidget(FloatLayout):
    def draw(self):
        # Create Backend
        # Draw Backend
        # Create Card() using Backend

        # Defining Card Data (Removed for imported Decks)
        backend_bewd = CardBackend('Blue Eyes White Dragon', 'bewd.png', 'One')
        backend_dragon = CardBackend('Dragon Egg', 'test.png', 'Two')
        backend_lava = CardBackend('Lava Golem', 'lavagolem.png', 'Three')

        # Creating Card Button Objects
        card_zero = Card()
        card_one = Card()
        card_two = Card()

        # Defining Card Title
        card_zero.main_pop.title = backend_lava.name
        card_one.main_pop.title = backend_dragon.name
        card_two.main_pop.title = backend_bewd.name

        # Defining Card Text for Scrollview
        card_zero.card_info.text = backend_bewd.effect

        # Defining Card Art
        card_zero.source = backend_bewd.card_art
        card_one.source = backend_dragon.card_art
        card_two.source = backend_lava.card_art

        deck_dictionary = {
            0: card_zero,
            1: card_one,
            2: card_two,
        }

        # Prototype Shuffle for top card
        # drawing = random.choice(deck_list)

        # Creating a Physical Card Object
        # drawn_card = Card()

        # OLD
        # Applying Card Data from backend to front end Card Object
        # drawn_card.main_pop.title = drawing.name
        # drawn_card.source = drawing.card_art
        # drawn_card.card_art.source = drawing.card_art
        # drawn_card.card_info.text = drawing.effect

        # Used to check somethings
        for x in range(0, 3):
            print(deck_dictionary[x].source)
            print(deck_dictionary[x].main_pop.title)

        self.ids.PlayerField.add_widget(random.choice(deck_dictionary), index=int(len(self.ids.PlayerField.children)/2))


class CardGameApp(App):
    def build(self):
        return PlayMatWidget()


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

Kivy文件:

<Card@ImageButton>:
    size_hint: 0.8,0.8
    pos_hint: {'x':0, 'y':0.1}
    on_press: print('confirming press')
    on_press: root.main_pop.open()

<PlayMatWidget>:
    id: PlayMat
    canvas:
        Rectangle:
            size: self.size
            pos: self.pos
            source: 'tron1.png'
    StackLayout:
        id: OppHand
        size_hint: 0.6, 0.1
        pos_hint: {'x':0.2,'y': 0.9}
        canvas:
            Rectangle:
                size: self.size
                pos: self.pos
                source: 'background.png'
    StackLayout:
        id: OppField
        size_hint: 0.6, 0.4
        pos_hint: {'x':0.2, 'y':0.5}
        canvas:
            Rectangle:
                size: self.size
                pos: self.pos
                source: 'background.png'
    StackLayout:
        id: cards
        size_hint: 0.6,0.4
        pos_hint: {'x':0.2, 'y':0.1}
        canvas:
            Rectangle:
                size: self.size
                pos: self.pos
                source: 'background.png'
    AnchorLayout:
        id: PlayerFieldAnchor
        anchor_x: 'center'
        anchor_y: 'center'
        size_hint: 0.6,0.4
        pos_hint: {'x':0.2, 'y':0.1}
        canvas.before:
            Rectangle:
                size: self.size
                pos: self.pos
                source: 'background.png'
        BoxLayout:
            id: PlayerField
            orientation: 'horizontal'
    StackLayout:
        id: PlayerHand
        orientation: 'lr-tb'
        size_hint: 0.6,0.1
        pos_hint: {'x': 0.2, 'y':0}
        canvas:
            Rectangle:
                size: self.size
                pos: self.pos
                source: 'background.png'
    ImageButton:
        id: PlayerDeck
        source: 'cardback.png'
        size_hint: 0.15, 0.15
        pos_hint: {'x':0.025,'y':0.05}
        on_press: root.draw()

Tags: textfromposimportselfbackendsourcesize
2条回答

1/每次重写__init__方法时,都需要调用super()方法,如果对kivy小部件不这样做,它们就会崩溃,因为它们的初始化不正确,对于Python3,我相信您希望这样做

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

2/通常在kivy中,创建属性并按名称传递它更容易,而不是将参数传递给init,这样您甚至不需要重写__init__,从而避免了1/中的错误。你知道吗

class CardBackend:
    name = StringProperty()
    card_art = StringProperty()
    effect = stringProperty()

…

card = CardBackend(
    name='Blue Eyes White Dragon',
    card_art='bewd.png',
    effect='One')

或者,用它来表示

CardBackend:
    name: 'Blue Eyes White Dragon'
    card_art: 'bewd.png'
    effect: 'One'

3/在Card中,您确实定义了类中的所有内容,而不是__init__,这意味着在定义类时,而不是创建实例时,将运行此代码,也许您实际上想要的是函数,而不是类?或者您想重写on_press方法的ImageButton,并使用卡的属性而不是当前使用的硬编码值将所有代码放入其中。你知道吗

我解决了。我将弹出框的创建移到一个带有Card类的函数中。在kivy文件中,我将inspect\u card()函数绑定到kivy card按钮的on\u press事件。你知道吗

以前,弹出窗口是在创建卡时定义的。因此,无论我点击哪个卡片按钮,弹出窗口中的信息总是与最新创建的卡片相对应。你知道吗

将其移动到某个函数意味着只有在该函数启动时才会创建弹出窗口,因此所有相关信息都对应于调用它的按钮的源信息。这样,实例是否在类中并不重要,因为它每次运行时都会被正确地重新定义。你知道吗

Success Video

卡类w/功能:

class Card(ImageButton):
    # Defining the Popup Window
    def inspect_card(self):
        main_pop = Popup()
        main_pop.title = 'Inspecting ' + self.cardname
        main_pop.title_align = 'center'
        main_pop.size_hint = None, None
        main_pop.size = 400, 400
        main_pop.auto_dismiss = False
        main_pop.opacity = 0.8

        # Variables or Variables to Be
        card_text = self.effecttext
        card_art = Image(source=self.source, size_hint=(.9, .85), pos_hint={'x': -0.18, 'y': .125})

        # Primary Child Widget
        main_box = FloatLayout()

        # Buttons
        play_button = Button(text='Play', size_hint=(0.32, 0.1), pos_hint={'x': 0.01, 'y': 0.0})
        discard_button = Button(text='Discard', size_hint=(0.32, 0.1), pos_hint={'x': 0.34, 'y': 0.0})
        close_button = Button(text='Close', size_hint=(0.32, 0.1), pos_hint={'x': 0.67, 'y': 0.0})
        close_button.bind(on_press=main_pop.dismiss)

        # Scrolling Card Text Viewer
        card_info = ScrollableLabel(text=card_text, size_hint=(0.45, .8), pos_hint={'x': .55, 'y': .15})

        # Building main_pop.content
        main_box.add_widget(play_button)
        main_box.add_widget(discard_button)
        main_box.add_widget(close_button)
        main_box.add_widget(card_info)
        main_box.add_widget(card_art)
        main_pop.content = main_box
        main_pop.open()

KivyCard按钮,带有弹出窗口的新绑定和引用属性

<Card@ImageButton>:
    size_hint: 0.8,0.8
    pos_hint: {'x':0, 'y':0.1}
    cardname: 'stuff'
    effecttext: 'ABCDEFGHIJKL123456789' * 30
    on_press: print('confirming press')
    on_press: root.inspect_card()

(列出的属性值是默认值,在将它们带到字段之前,我在MainGameWidget下面更改它们。我稍后会将大部分内容移到Deckbuilder功能中)

相关问题 更多 >