Python Kivy 使用kwargs时的KeyError
我正在写一个程序,用来计算不同田径项目的配速。我想设置一个变量,表示用户选择的要计算的项目。
下面是.py文件的相关部分
class InitialScreen(Screen):
def press(self, *args, **kwargs):
if kwargs['event'] == '600':
eventpress = 'event600'
App.get_running_app().root.current = 'calculatorbelow_screen'
if kwargs['event'] == '800':
eventpress = 'event800'
App.get_running_app().root.current = 'calculatorbelow_screen'
return eventpress
下面是.kv文件的相关部分
<InitialScreen>:
name: "initial"
GridLayout:
size: root.width, root.height
rows:5
GridLayout:
cols: 1
Label:
text: "Choose your event"
font_size: 60
bold: True
GridLayoutInitial:
ButtonEventRow1:
id: event600
text: "600m"
on_press: root.press(event='600')
ButtonEventRow1:
id: event800
text: "800m"
on_press: root.press(event='800')
错误信息如下:
文件 "D:\PYTHON PROJECTS\PROJECT 1\Pace Calculator\pacemain.py",第24行,在press函数中 if kwargs['event'] == '600': ~~~~~~^^^^^^^^^ KeyError: 'event'
完整的.py文件如下
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.graphics import Color, Rectangle
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.properties import ListProperty
kivy.require("2.3.0")
Window.clearcolor = 0, .5, 1, 1
class InitialScreen(Screen):
def press(self, *args, **kwargs):
if kwargs['event'] == '600':
eventpress = 'event600'
App.get_running_app().root.current = 'calculatorbelow_screen'
if kwargs['event'] == '800':
eventpress = 'event800'
App.get_running_app().root.current = 'calculatorbelow_screen'
return eventpress
class CalculatorScreenBelowMile(Screen):
#def __init__(self, **kwargs):
#super().__init__(**kwargs)
def press_calculate_below(self, **kwargs):
splitslist = []
userevent = InitialScreen().press()
resultsbelow = self.ids.inputbelow.text
if userevent == 'event600':
splitsdividing = [6, 3, 2, 1.5]
if userevent == 'event800':
splitsdividing = [8,4,2.67,2]
if userevent == 'event1000':
splitsdividing = [10, 5, 3.33, 2.5]
if userevent == 'event1mile':
splitsdividing = [16, 8, 5.33, 4]
for i in splitsdividing:
results = resultsbelow
results = int(results)
results = results / i
results = int(results) #removes decimals
results = str(results)
splitslist.append(results)
print(splitslist)
self.ids.event100split.text = (splitslist[0])
self.ids.event200split.text = (splitslist[1])
self.ids.event300split.text = (splitslist[2])
self.ids.event400split.text = splitslist[3]
def press_return(self, **kwargs):
App.get_running_app().root.current = "initial"
class CalculatorScreenAboveMile(Screen): #Have not started on this yet
def press(self):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file('pacemain.kv')
class MainApp(App):
def build(self):
return kv
if __name__=="__main__":
MainApp().run()
最后,完整的.kv文件如下(注意我特别在问关于CalculatorScreenBelowMile,而不是CalculatorScreenAboveMile)
WindowManager:
InitialScreen:
CalculatorScreenBelowMile:
CalculatorScreenAboveMile:
<ButtonEventRow1@Button>
background_color: 0,0,1,1
<ButtonEventRow2@Button>
background_color: 1,0,0,1
<ButtonEventRow3@Button>
background_color: 0,1,0,1
<GridLayoutInitial@GridLayout>
cols: 2
<LabelSplits@Label>
background_color: 0,0,1,1
canvas.before:
Color:
rgba: self.background_color
Rectangle:
size: self.size
pos:self.pos
size_hint: (.5,.5)
font_size: 40
#<pressResults@press>:
<Button>:
font_size: 60
<GridLayout>:
spacing: 10
<InitialScreen>:
name: "initial"
GridLayout:
size: root.width, root.height
rows:5
GridLayout:
cols: 1
Label:
text: "Choose your event"
font_size: 60
bold: True
GridLayoutInitial:
ButtonEventRow1:
id: event600
text: "600m"
on_press: root.press(event='600')
ButtonEventRow1:
id: event800
text: "800m"
on_press: root.press(event='800')
GridLayoutInitial:
ButtonEventRow2:
text: "1000m"
on_press: root.press(event='1000')
ButtonEventRow2:
text: "1 Mile"
on_press: root.press(event='1mile')
GridLayoutInitial:
ButtonEventRow3:
text: "5000m"
#on_release: app.root.current = "calculatorabove"
ButtonEventRow3:
text: "10000m"
#on_release: app.root.current = "calculatorabove"
<CalculatorScreenBelowMile>: #Distances of mile and below
name: "calculatorbelow_screen"
GridLayout:
cols:1
size: root.width, root.height
GridLayout: #Top of page
cols:1
Label:
text: "Pace Calculator. Enter your time in seconds."
font_size: 28
Label:
text: "Ex: 120"
font_size: 50
bold: True
GridLayout: #Enter time and Userinput, calculate and unit
cols:2
Label:
text: "Enter your time here:"
bold: True
font_size: 40
pos_hint_x: .5
pos_hint_y: .8
TextInput:
multiline: False
id: inputbelow
Button:
text: "Calculate"
on_press: root.press_calculate_below()
Button:
text: "Switch unit"
#ADD SOMETHING HERE
GridLayout:
cols: 2
GridLayout: #Return bottom right
cols: 2
rows: 4
LabelSplits:
text: "100m:"
LabelSplits:
id: event100split
text: ""
LabelSplits:
text: "200m:"
LabelSplits:
id: event200split
text: ""
LabelSplits:
text: "300m:"
LabelSplits:
id: event300split
text: ""
LabelSplits:
text: "400m:"
LabelSplits:
id: event400split
text: ""
GridLayout:
cols: 1
Button:
text: "Return"
on_press: root.press_return()
<CalculatorScreenAboveMile>: #Distances of above mile
name: "calculatorabove_screen"
GridLayout:
cols:1
size: root.width, root.height
GridLayout: #Top of page
cols:1
Label:
text: "Pace Calculator. Enter your time in seconds."
font_size: 28
Label:
text: "Ex: 120"
font_size: 50
bold: True
GridLayout: #Enter time and Userinput, calculate and unit
cols:2
Label:
text: "Enter your time here:"
bold: True
font_size: 40
pos_hint_x: .5
pos_hint_y: .8
TextInput:
multiline: False
id: inputbelow
Button:
text: "Calculate"
on_press: root.press()
#on_press: app.calculatorbelow()
#on_press: app.root.current = "resultsabove"
Button:
text: "Switch unit"
#ADD SOMETHING HERE
GridLayout:
cols: 2
GridLayout: #Return bottom right
cols: 2
rows: 4
LabelSplits:
text: "400m:"
LabelSplits:
id: event400split
text: ""
LabelSplits:
text: "800m:"
LabelSplits:
id: event800split
text: ""
LabelSplits:
text: "1200m:"
LabelSplits:
id: event1200split
text: ""
LabelSplits:
text: "1600m:"
LabelSplits:
id: event1600split
text: ""
GridLayout:
cols: 1
Button:
text: "Return"
on_press: app.root.current = "initial"
我尝试过其他方法来设置一个变量,等于用户选择的项目,但如果你知道其他的方法,我很想听听,因为我对kivy还很陌生,对Python和面向对象编程也还不太熟悉。
1 个回答
0
解决这个问题的一种方法是,在你的 CalculatorScreenBelowMile
界面中保存一个事件的引用。你可以通过在这个类里面添加一个 eventpress
属性来实现:
class CalculatorScreenBelowMile(Screen):
eventpress = StringProperty('')
接着,在你的 press()
方法里设置这个属性:
class InitialScreen(Screen):
def press(self, *args, **kwargs):
eventpress = None
if kwargs['event'] == '600':
eventpress = 'event600'
App.get_running_app().root.current = 'calculatorbelow_screen'
if kwargs['event'] == '800':
eventpress = 'event800'
App.get_running_app().root.current = 'calculatorbelow_screen'
self.manager.get_screen('calculatorbelow_screen').eventpress = eventpress # set event in the CalculatorScreenBelowMile Screen
# return eventpress
然后在你的 press_calculate_below()
方法中使用这个保存下来的事件:
def press_calculate_below(self, **kwargs):
splitslist = []
# userevent = InitialScreen().press()
userevent = self.eventpress # use saved event
resultsbelow = self.ids.inputbelow.text
if userevent == 'event600':
splitsdividing = [6, 3, 2, 1.5]
if userevent == 'event800':
splitsdividing = [8,4,2.67,2]
if userevent == 'event1000':
splitsdividing = [10, 5, 3.33, 2.5]
if userevent == 'event1mile':
splitsdividing = [16, 8, 5.33, 4]