Kivy,Python - 使用 ScreenManager 时应用程序中的功能不起作用
Kivy, Python - Functions in app not working when using ScreenManager
我的应用程序在我使用 ScreenManager 后就无法运行。
我的秒表功能有问题 。简而言之,秒表需要在暂停按钮打开弹出菜单时暂停,并在菜单关闭时恢复。
使用ScreenManager时返回的问题,所以我可能没有正确使用ScreenManager,或者缺少一些关于Kivy或Python做我想做的事情的必要基础知识。
Python代码:
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.popup import Popup
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
root_widget = Builder.load_file('app.kv')
class ExampleWidget(Screen):
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 start(self):
# Keeping time
self.time = 0
Clock.schedule_interval(self.increment_time, .1)
def stop(self):
Clock.unschedule(self.increment_time)
print('Stopped')
def pause(self):
# Pause stopwatch
if 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 Menu(Screen, BoxLayout):
pass
class WindowManager(ScreenManager):
pass
class MyApp(App):
ExampleWidget = ExampleWidget()
WindowManager = WindowManager()
def build(self):
return self.WindowManager
MyApp().run()
.kv 文件:
#:import Factory kivy.factory.Factory
#: import WipeTransition kivy.uix.screenmanager.WipeTransition
<WindowManager>:
transition: WipeTransition()
canvas.before:
Color:
rgba: 0, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
Menu:
ExampleWidget:
<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.pause()
size: self.size
<Menu>:
id: menu
name: "first"
orientation: 'vertical'
size: root.width, root.height
secondary_color: .4,.4,.4,1
secondary_color2: 0,.7,.7,1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Button:
id: start_button
text: "Start"
font_size: 32
on_release: app.root.current = "second"
size: root.width/2, root.height/12
size_hint: None, None
pos: root.width/4, root.height/2.5
background_color: 0, 0, 0, 0
canvas.before:
Color:
rgba: menu.secondary_color if start_button.state=='normal' else menu.secondary_color2
RoundedRectangle:
size: start_button.width, start_button.height
pos: start_button.pos
<ExampleWidget>:
name: 'second'
GridLayout:
col: 2
rows: 3
size: root.size
Button:
text: 'start'
size: self.size
on_press: root.start()
Button:
text: 'stop'
size: self.size
on_press: root.stop()
Button:
text: 'Pause menu'
size: self.size
on_press: root.paused = True
on_release: Factory.PopupMenu().open(); root.pause()
Label:
text: str(round(root.time))
size: self.size
提前感谢您的帮助或想法。
它不起作用的原因是因为您在弹出窗口(您在应用程序中创建的那个)中使用了 ExampleWidget 的新实例。但是您应该访问的是您在 ScreenManager 中添加的那个。
要访问它,您可以改为执行类似的操作。
<WindowManager>:
example: example
ExampleWidget:
id: example
# and in popup
example: app.root.example
问题是您引用了不属于您的 GUI 的 ExampleWidget
。代码:
class PopupMenu(Popup):
example = ExampleWidget()
正在创建对 ExampleWidget
的新实例的引用,该实例不是您的 GUI 中的实例。这可以替换为:
class PopupMenu(Popup):
pass
然后,在您的 kv
中,如果您为实际位于 GUI 中的 ExampleWidget
实例添加 id
:
<WindowManager>:
transition: WipeTransition()
canvas.before:
Color:
rgba: 0, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
Menu:
ExampleWidget:
id: example # added to enable accessing this instance of ExampleWidget
现在你的 MyApp
class 可以是:
class MyApp(App):
WindowManager = WindowManager()
def build(self):
self.ExampleWidget = self.WindowManager.ids.example
return self.WindowManager
现在 app.ExampleWidget
将成为对 GUI 中 ExampleWidget
实例的引用。
我的应用程序在我使用 ScreenManager 后就无法运行。
我的秒表功能有问题
使用ScreenManager时返回的问题,所以我可能没有正确使用ScreenManager,或者缺少一些关于Kivy或Python做我想做的事情的必要基础知识。
Python代码:
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.popup import Popup
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
root_widget = Builder.load_file('app.kv')
class ExampleWidget(Screen):
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 start(self):
# Keeping time
self.time = 0
Clock.schedule_interval(self.increment_time, .1)
def stop(self):
Clock.unschedule(self.increment_time)
print('Stopped')
def pause(self):
# Pause stopwatch
if 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 Menu(Screen, BoxLayout):
pass
class WindowManager(ScreenManager):
pass
class MyApp(App):
ExampleWidget = ExampleWidget()
WindowManager = WindowManager()
def build(self):
return self.WindowManager
MyApp().run()
.kv 文件:
#:import Factory kivy.factory.Factory
#: import WipeTransition kivy.uix.screenmanager.WipeTransition
<WindowManager>:
transition: WipeTransition()
canvas.before:
Color:
rgba: 0, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
Menu:
ExampleWidget:
<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.pause()
size: self.size
<Menu>:
id: menu
name: "first"
orientation: 'vertical'
size: root.width, root.height
secondary_color: .4,.4,.4,1
secondary_color2: 0,.7,.7,1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Button:
id: start_button
text: "Start"
font_size: 32
on_release: app.root.current = "second"
size: root.width/2, root.height/12
size_hint: None, None
pos: root.width/4, root.height/2.5
background_color: 0, 0, 0, 0
canvas.before:
Color:
rgba: menu.secondary_color if start_button.state=='normal' else menu.secondary_color2
RoundedRectangle:
size: start_button.width, start_button.height
pos: start_button.pos
<ExampleWidget>:
name: 'second'
GridLayout:
col: 2
rows: 3
size: root.size
Button:
text: 'start'
size: self.size
on_press: root.start()
Button:
text: 'stop'
size: self.size
on_press: root.stop()
Button:
text: 'Pause menu'
size: self.size
on_press: root.paused = True
on_release: Factory.PopupMenu().open(); root.pause()
Label:
text: str(round(root.time))
size: self.size
提前感谢您的帮助或想法。
它不起作用的原因是因为您在弹出窗口(您在应用程序中创建的那个)中使用了 ExampleWidget 的新实例。但是您应该访问的是您在 ScreenManager 中添加的那个。 要访问它,您可以改为执行类似的操作。
<WindowManager>:
example: example
ExampleWidget:
id: example
# and in popup
example: app.root.example
问题是您引用了不属于您的 GUI 的 ExampleWidget
。代码:
class PopupMenu(Popup):
example = ExampleWidget()
正在创建对 ExampleWidget
的新实例的引用,该实例不是您的 GUI 中的实例。这可以替换为:
class PopupMenu(Popup):
pass
然后,在您的 kv
中,如果您为实际位于 GUI 中的 ExampleWidget
实例添加 id
:
<WindowManager>:
transition: WipeTransition()
canvas.before:
Color:
rgba: 0, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
Menu:
ExampleWidget:
id: example # added to enable accessing this instance of ExampleWidget
现在你的 MyApp
class 可以是:
class MyApp(App):
WindowManager = WindowManager()
def build(self):
self.ExampleWidget = self.WindowManager.ids.example
return self.WindowManager
现在 app.ExampleWidget
将成为对 GUI 中 ExampleWidget
实例的引用。