Python,Kivy:从不同 classes/screens 调用函数时出现问题
Python, Kivy: Problem with calling functions from different classes/screens
我在正确调用来自不同 类 的函数时遇到问题。
我正在制作一个简单的游戏,它使用通关所需的时间来计算分数。背景中有一个秒表 运行,我想在弹出菜单中添加一个暂停按钮,并在此弹出菜单中添加一个恢复按钮。
问题是,当从弹出菜单中调用暂停函数时,它也会在弹出菜单中返回,而不是在主窗口小部件中返回。
这里是代码的简化版本:
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.widget import Widget
from kivy.uix.popup import Popup
from kivy.clock import Clock
root_widget = Builder.load_file('app.kv')
class ExampleWidget(Widget):
time = NumericProperty(0)
paused = False
stop = False
# Keeping time
def increment_time(self, interval):
self.time += .1
print(self.time) # To check if stopwatch is running or not
# Stop should mean that the stopwatch must reset when it starts again.
# When paused it should resume when it starts again
def stop_start_or_pause(self):
# stop stopwatch
if self.stop:
Clock.unschedule(self.increment_time)
print('Stopped')
# Make sure time is 0 when restarting
elif not self.stop and not self.paused:
# Keeping time
self.time = 0
Clock.schedule_interval(self.increment_time, .1)
# Pause stopwatch
elif self.paused:
Clock.unschedule(self.increment_time)
print("!!", self.time) # To make it easier to see if stopwatch actually resumes where it left off
print('unscheduled') # Just to confirm and to make it a bit easier to see
# resume stopwatch
elif not self.paused:
Clock.schedule_interval(self.increment_time, .1)
class PopupMenu(Popup):
example = ExampleWidget()
class MyApp(App):
ExampleWidget = ExampleWidget()
def build(self):
return ExampleWidget()
MyApp().run()
.kv 文件:
#:import Factory kivy.factory.Factory
<PopupMenu@Popup>
auto_dismiss: False
size_hint_y: .8
size_hint_x: .9
title: 'Pause'
example: app.ExampleWidget
BoxLayout:
Button:
text: 'resume'
on_press: root.example.paused = False
on_release: root.dismiss(); root.example.stop_start_or_pause()
size: self.size
<ExampleWidget>:
GridLayout:
col: 2
rows: 3
size: root.size
Button:
text: 'start'
size: self.size
on_press: root.stop = False; root.stop_start_or_pause()
Button:
text: 'stop'
size: self.size
on_press: root.stop = True; root.stop_start_or_pause()
Button:
text: 'Pause menu'
size: self.size
on_press: root.paused = True
on_release: Factory.PopupMenu().open(); root.stop_start_or_pause()
Label:
text: str(round(root.time))
size: self.size
我尝试制作一个函数并使用 Clock.schedule.interval() 继续检查是否暂停 == True,但它不断返回:
AttributeError: 'float' object has no attribute 'stopped'
无论如何,这似乎都不是有效的解决方案,因此我不想在此功能上花费太多时间。我还尝试查找 'stupid' 错误(即“,”而不是“.”),但那是在我意识到恢复按钮返回 'second' 秒表而不是更新我真正想使用的秒表之前.
我希望有人能提供帮助,并且我的问题很清楚。英语不是我的第一语言,所以我有时很难找到 explain/ask 问题的最佳方式。
提前致谢!
如果我理解你的问题,问题出在你的 MyApp
class:
class MyApp(App):
ExampleWidget = ExampleWidget()
def build(self):
return ExampleWidget()
此代码正在创建 ExampleWidget
的两个实例。一个在build()
方法中返回,一个保存为MyApp
的ExampleWidget
属性。现在,当您使用 MyApp
的 ExampleWidget
属性时,您没有引用作为 GUI 根的 ExampleWidget
,因此它对屏幕上显示的内容没有影响。解决方法是只创建一个 ExampleWidget
实例,如下所示:
class MyApp(App):
ExampleWidget = ExampleWidget()
def build(self):
return self.ExampleWidget
我在正确调用来自不同 类 的函数时遇到问题。
我正在制作一个简单的游戏,它使用通关所需的时间来计算分数。背景中有一个秒表 运行,我想在弹出菜单中添加一个暂停按钮,并在此弹出菜单中添加一个恢复按钮。
问题是,当从弹出菜单中调用暂停函数时,它也会在弹出菜单中返回,而不是在主窗口小部件中返回。
这里是代码的简化版本:
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.widget import Widget
from kivy.uix.popup import Popup
from kivy.clock import Clock
root_widget = Builder.load_file('app.kv')
class ExampleWidget(Widget):
time = NumericProperty(0)
paused = False
stop = False
# Keeping time
def increment_time(self, interval):
self.time += .1
print(self.time) # To check if stopwatch is running or not
# Stop should mean that the stopwatch must reset when it starts again.
# When paused it should resume when it starts again
def stop_start_or_pause(self):
# stop stopwatch
if self.stop:
Clock.unschedule(self.increment_time)
print('Stopped')
# Make sure time is 0 when restarting
elif not self.stop and not self.paused:
# Keeping time
self.time = 0
Clock.schedule_interval(self.increment_time, .1)
# Pause stopwatch
elif self.paused:
Clock.unschedule(self.increment_time)
print("!!", self.time) # To make it easier to see if stopwatch actually resumes where it left off
print('unscheduled') # Just to confirm and to make it a bit easier to see
# resume stopwatch
elif not self.paused:
Clock.schedule_interval(self.increment_time, .1)
class PopupMenu(Popup):
example = ExampleWidget()
class MyApp(App):
ExampleWidget = ExampleWidget()
def build(self):
return ExampleWidget()
MyApp().run()
.kv 文件:
#:import Factory kivy.factory.Factory
<PopupMenu@Popup>
auto_dismiss: False
size_hint_y: .8
size_hint_x: .9
title: 'Pause'
example: app.ExampleWidget
BoxLayout:
Button:
text: 'resume'
on_press: root.example.paused = False
on_release: root.dismiss(); root.example.stop_start_or_pause()
size: self.size
<ExampleWidget>:
GridLayout:
col: 2
rows: 3
size: root.size
Button:
text: 'start'
size: self.size
on_press: root.stop = False; root.stop_start_or_pause()
Button:
text: 'stop'
size: self.size
on_press: root.stop = True; root.stop_start_or_pause()
Button:
text: 'Pause menu'
size: self.size
on_press: root.paused = True
on_release: Factory.PopupMenu().open(); root.stop_start_or_pause()
Label:
text: str(round(root.time))
size: self.size
我尝试制作一个函数并使用 Clock.schedule.interval() 继续检查是否暂停 == True,但它不断返回:
AttributeError: 'float' object has no attribute 'stopped'
无论如何,这似乎都不是有效的解决方案,因此我不想在此功能上花费太多时间。我还尝试查找 'stupid' 错误(即“,”而不是“.”),但那是在我意识到恢复按钮返回 'second' 秒表而不是更新我真正想使用的秒表之前.
我希望有人能提供帮助,并且我的问题很清楚。英语不是我的第一语言,所以我有时很难找到 explain/ask 问题的最佳方式。
提前致谢!
如果我理解你的问题,问题出在你的 MyApp
class:
class MyApp(App):
ExampleWidget = ExampleWidget()
def build(self):
return ExampleWidget()
此代码正在创建 ExampleWidget
的两个实例。一个在build()
方法中返回,一个保存为MyApp
的ExampleWidget
属性。现在,当您使用 MyApp
的 ExampleWidget
属性时,您没有引用作为 GUI 根的 ExampleWidget
,因此它对屏幕上显示的内容没有影响。解决方法是只创建一个 ExampleWidget
实例,如下所示:
class MyApp(App):
ExampleWidget = ExampleWidget()
def build(self):
return self.ExampleWidget