[英]Python Kivy - Call methods across different class
我是編碼新手,與 Python 一起工作了幾個月,並試圖全神貫注於 Kivy。我認為對此有一個簡單的解決方案,但在從另一個 class 中調用方法時,我很掙扎。 甚至不確定這是否可能,我的 OOP 不會很強!!
如果有人能向我解釋這一點,我將不勝感激。 我在網上看過,但仍在努力了解我需要做什么。
我有一個簡單的代碼,它有一個 label 和 3 個切換按鈕,label 文本更改以顯示按下了多少個切換按鈕。 下面是原始代碼。
我想要做的是使用循環創建切換按鈕,以便可以輕松更改切換按鈕的數量。 我已經實現了這一點,但是當我嘗試將該方法綁定到切換按鈕時,代碼失敗了。 我還嘗試在“Tbtn”class 中定義一個方法來調用 Main.Counter(),但這也不起作用。
線路
self.bind(on_state = Main.counter())
我認為在切換按鈕的初始部分是我出錯的地方。
任何幫助甚至解釋都會很棒。 這不是我第一次被困在這上面了!! 謝謝
原始代碼:
from kivy.app import App
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import NumericProperty
class Tbtn(ToggleButton):
pass
class Header_Box(BoxLayout):
pass
class Counter(BoxLayout):
pass
class Main(BoxLayout):
count = NumericProperty()
def counter(self,widget):
toggles = []
for child in self.ids.Seat_Box.children:
if isinstance(child, ToggleButton):
if child.state == 'down':
toggles.append(child.text)
self.count = len(toggles)
print(self.count)
class TestApp(App):
def build(self):
return Main()
TestApp().run()
KV文件:
<Main>:
name: "main"
BoxLayout:
orientation: "vertical"
Header_Box:
Label:
text: str(root.count)
Counter:
id: Seat_Box
Tbtn:
id: btn1
on_state: root.counter(self)
Tbtn:
id: btn2
on_state: root.counter(self)
Tbtn:
id: btn2
on_state: root.counter(self)
使用 for 循環的代碼:
from kivy.app import App
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import NumericProperty
class Tbtn(ToggleButton):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.bind(on_state = Main().counter())
class Header_Box(BoxLayout):
pass
class Counter(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
for x in range(3):
btn = Tbtn()
self.add_widget(btn)
class Main(BoxLayout):
count = NumericProperty()
def counter(self,widget):
toggles = []
for child in self.ids.Seat_Box.children:
if isinstance(child, ToggleButton):
if child.state == 'down':
toggles.append(child.text)
self.count = len(toggles)
print(self.count)
class TestApp(App):
def build(self):
return Main()
TestApp().run()
KV文件:
<Main>:
name: "main"
BoxLayout:
orientation: "vertical"
Header_Box:
Label:
text: str(root.count)
Counter:
id: Seat_Box
首先,刪除self.bind(on_state = Main().counter())
。
我建議你解決這個 in.kv 方面。
方式 1-.kv 端:在您的 .kv 文件下方添加:
<Tbtn>:
on_state: app.get_running_app().root.counter(self)
Way 2-.py side:在Tbtn class中添加這個。
def on_release(self):
App.get_running_app().root.counter(self)
雖然其他答案已經解決了您的問題,但以下內容讓我發布了這個問題。
任何幫助甚至解釋都會很棒......
從技術上講,以下行,
self.bind(on_state = Main().counter())
由於各種原因是錯誤的。 讓我們試着弄清楚這一點。
on_state
方法是一種通用方法,不是默認事件(如on_press
等)。 這就是為什么bind(on_state = some_callback)
不起作用的原因。
您再次執行Main().counter()
,它實際上創建了Main
的一個新實例(它可能與root
相關,也可能不相關,這里當然不是)並分配給它的方法。
您似乎只想訪問Main
小部件(恰好是此處的root
小部件)方法之一。
由於您使用kvlang
,因此可以按如下方式更有效地完成此操作,
<Tbtn>:
on_state: app.root.counter()
您可以在kvlang
文檔中找到更多相關信息。
現在在.py
中,您只需定義 class 以及其他一些更改,
class Tbtn(ToggleButton):
pass
.
.
.
class Main(BoxLayout):
count = NumericProperty()
def counter(self): # Pass no extra args as you haven't done in 'on_state' method.
toggles = []
.
.
.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.