我想将一个来自main.py中的计时器的值传递给exit.kv文件中的ProgressBar,但是使用类似于showcase示例的文件结构。我试图制作一个定时按钮,以便程序不会意外退出,我需要按住按钮几秒钟。
已经尝试了很多东西,但我无法找到解决方案。
该项目需要将main.py中读取的更多值(使用我的Raspberry pi上的DAC)传递给几个不同的.kv文件
这是我的第一个Kivy项目,也是我的第一个Python项目,所以学习曲线对我来说很陡峭。
修改
我需要的是将main.py文件中的( exit_time )值传递给exit.kv文件中的ProgressBar( exit_bar )以显示在退出程序之前,我需要多长时间按下按钮( exit_button )。
当程序运行时,python控制台将执行倒计时,但我无法在ProgressBar(或标签或exit.kv文件中的任何内容)中显示它。
如何查找是否需要使用应用。或根。或者screen.ids.exit_bar.value还是什么?
再次编辑:解决方案
我删除了main.py中有关计时器的所有内容,并将其放入main.py;
#
# The Exit Timer, counting up to 20 from 0 before exiting.
# If Press button start Timer. If button up, reset timer
#
def my_callback(self, dt):
global exit_time
exit_time += 1
if exit_time == 101:
sys.exit("piMote stopped!")
self.time = exit_time
def start_exit_timer(self):
Clock.schedule_interval(self.my_callback, 0.01)
def stop_exit_timer(self):
global exit_time
Clock.unschedule(self.my_callback)
Clock.schedule_once(self.my_callback,0)
exit_time = -1
然后我将exit.ky的一部分更改为
ProgressBar:
id: exit_bar
max: 100
value: app.time
size_hint_x: .3
size_hint_y: None
height: '10dp'
实际上我需要做的就是添加 self.time = exit_time"
main.py
from time import time
from kivy.app import App
from os.path import dirname, join
from kivy.lang import Builder
from kivy.properties import NumericProperty, StringProperty, BooleanProperty,\
ListProperty
from kivy.clock import Clock
from kivy.uix.screenmanager import Screen
from kivy.uix.checkbox import CheckBox
import os
import sys
from kivy.config import Config
exit_time = 0
timer_start = 0
class ShowcaseScreen(Screen):
fullscreen = BooleanProperty(False)
def add_widget(self, *args):
if 'content' in self.ids:
return self.ids.content.add_widget(*args)
return super(ShowcaseScreen, self).add_widget(*args)
class ShowcaseApp(App):
index = NumericProperty(-1)
current_title = StringProperty()
time = NumericProperty(0)
screen_names = ListProperty([])
hierarchy = ListProperty([])
exit_time = NumericProperty(21)
def build(self):
self.title = 'hello world'
self.screens = {}
self.available_screens = [
'Exit']
self.screen_names = self.available_screens
curdir = dirname(__file__)
self.available_screens = [join(curdir,
'{}.kv'.format(fn)) for fn in self.available_screens]
screen = self.load_screen(self.index +1)
self.current_title = screen.name
#
# choose the right screen from spinner
#
def on_current_title(self, instance, value):
self.root.ids.spnr.text = value
def go_screen(self, idx):
print self.index
self.index = idx
self.root.ids.sm.switch_to(self.load_screen(idx), direction='left')
def load_screen(self, index):
if index in self.screens:
return self.screens[index]
screen = Builder.load_file(self.available_screens[index].lower())
self.screens[index] = screen
return screen
#
# timer start for joystick and exit timer
#
def __init__(self,**kwargs):
super(ShowcaseApp,self).__init__(**kwargs)
Clock.schedule_interval(self.my_timer, 0.1)
#
# The Exit Timer, counting up to 20 from 0 before exiting.
# If Press button start Timer. If button up, reset timer
#
def my_timer(screen, dt):
if timer_start == 1:
global exit_time
exit_time += 1
if exit_time == 21:
sys.exit("piMote stopped!")
print exit_time
return exit_time + 7
#################################################################
# Need to do something here to make the timer-progressbar #
# move, counting how long the button is pressed #
#################################################################
def start_exit_timer(self):
global timer_start
timer_start = 1
def stop_exit_timer(self):
global timer_start, exit_time
exit_time = 0
timer_start = 0
if __name__ == '__main__':
ShowcaseApp().run()
showcase.kv
#:kivy 1.8.0
#:import Factory kivy.factory.Factory
<ActionSpinnerOptions@SpinnerOption>
background_color: .4, .4, .4, 1
<ActionSpinner@Spinner+ActionItem>
canvas.before:
Color:
rgba: 0.128, 0.128, 0.128, 1
Rectangle:
size: self.size
pos: self.pos
border: 27, 20, 12, 12
#background_normal: 'atlas://data/images/defaulttheme/action_group'
option_cls: Factory.ActionSpinnerOptions
<ShowcaseScreen>:
ScrollView:
do_scroll_x: False
do_scroll_y: False if root.fullscreen else (content.height > root.height - dp(16))
AnchorLayout:
size_hint_y: None
height: root.height if root.fullscreen else max(root.height, content.height)
GridLayout:
id: content
cols: 1
spacing: '8dp'
padding: '8dp'
size_hint: (1, 1) if root.fullscreen else (.8, None)
height: self.height if root.fullscreen else self.minimum_height
BoxLayout:
orientation: 'vertical'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
size: self.size
#source: 'data/background.png'
ActionBar:
ActionView:
id: av
ActionPrevious:
title: 'piMote'
ActionSpinner:
id: spnr
important: True
text: 'Jump to Screen'
values: app.screen_names
on_text:
if sm.current != args[1]:\
idx = app.screen_names.index(args[1]);\
app.go_screen(idx)
ScreenManager:
id: sm
on_current_screen:
spnr.text = args[1].name
idx = app.screen_names.index(args[1].name)
if idx > -1: app.hierarchy.append(idx)
exit.kv
ShowcaseScreen:
name: 'Exit'
Label:
id: exit_label1
text: "Are you really sure\n you want to quit?"
size_hint_y: None
height: '36dp'
ProgressBar:
id: exit_bar
max: 20
#value: app.my_timer()
size_hint_x: .3
size_hint_y: None
height: '10dp'
Button:
id: exit_button
text: "Yes"
size_hint_x: .2
size_hint_y: None
height: '48dp'
on_press: app.start_exit_timer()
on_release: app.stop_exit_timer()
答案 0 :(得分:0)
你的解决方案有点过于复杂......你只能衡量自新闻发布以来的时间,然后决定退出。
#forget about all the timers code...
import time #gonna need this
EXIT_BUTTON_TIME = 2.0 # 2 seconds is OK?
...
def exit_button_pressed(self):
self.exit_pressed = time.time()
def exit_button_release(self):
if time.time() - self.exit_pressed > EXIT_BUTTON_TIME:
exit() # or something else you want to do
同时更改KV文件中的功能名称......
...
on_press: app.exit_button_pressed()
on_release: app.exit_button_release()
我并不是说您的方法无法工作,但它更复杂(import this)