python - 同时运行kivy和无限循环
问题描述
我需要倒计时,然后在手机上使用。我听说 kivy 是手机的好图形,所以我尝试使用它。我试图同时运行无限的while循环来倒计时和创建窗口并显示剩余时间的kivy应用程序。我也在使用 pygame 时钟来计时。但是当我运行这段代码时,while循环正在计算时间,但它只会创建白色的空白窗口,一段时间后会创建另一个窗口。我究竟做错了什么 ?
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.uix.image import Image
from kivy.core.window import Window
from multiprocessing import Process
import pygame
class MyFloat(FloatLayout):
def __init__(self, **kwargs):
super(MyFloat, self).__init__(**kwargs)
self.background = Image(source="textures/background.jpg", allow_stretch=True, keep_ratio=False)
self.add_widget(self.background)
class MyApp(App):
def build(self):
return MyFloat()
def check_time():
global days
global hours
global minutes
global seconds
global miliSeconds
miliSeconds -= 1
if miliSeconds < 0:
miliSeconds += 100
seconds -= 1
if seconds < 0:
seconds += 60
minutes -= 1
if minutes < 0:
minutes += 60
hours -= 1
if hours < 0:
hours += 24
days -= 1
if days < 0:
global active
active = False
print("End")
print("days: ", days)
print("hours: ", hours)
print("minutes: ", minutes)
print("seconds: ", seconds)
print("miliseconds: ", miliSeconds)
def loop():
while active:
check_time()
clock.tick(100)
clock = pygame.time.Clock()
days = 0
hours = 0
minutes = 0
seconds = 30
miliSeconds = 0
active = True
if __name__ == "__main__":
p1 = Process(target=loop)
p2 = Process(target=MyApp().run)
p1.start()
p2.start()
解决方案
你不需要也不需要pygame
因为while True
有kivy
类时钟功能
# call my_callback every 0.5 seconds
Clock.schedule_interval(my_callback, 0.5)
# call my_callback in 5 seconds
Clock.schedule_once(my_callback, 5)
# call my_callback as soon as possible (usually next frame.)
Clock.schedule_once(my_callback)
开始任务:
task = Clock.schedule_interval(check_time, 0.1)
停止任务:
task.cancel()
并且您的函数将delta_time
在两次执行之间执行,因此您可以检查它是否恰好在之后执行0.1 second
。您可以使用它来显示正确的时间。
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.uix.image import Image
from kivy.core.window import Window
from kivy.clock import Clock
class MyFloat(FloatLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.background = Image(source="textures/background.jpg", allow_stretch=True, keep_ratio=False)
self.add_widget(self.background)
class MyApp(App):
def build(self):
return MyFloat()
def check_time(dt):
global days
global hours
global minutes
global seconds
global miliSeconds
global active
miliSeconds -= 1
if miliSeconds < 0:
miliSeconds += 100
seconds -= 1
if seconds < 0:
seconds += 60
minutes -= 1
if minutes < 0:
minutes += 60
hours -= 1
if hours < 0:
hours += 24
days -= 1
if days < 0:
active = False
print("End")
task.cancel() # <-- stoping task
print("days: ", days)
print("hours: ", hours)
print("minutes: ", minutes)
print("seconds: ", seconds)
print("miliseconds: ", miliSeconds)
days = 0
hours = 0
minutes = 0
seconds = 1
miliSeconds = 0
active = True
if __name__ == "__main__":
task = Clock.schedule_interval(check_time, 0.1) # <-- starting task
MyApp().run()
编辑:
Clock
用于显示当前时间的示例Label
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.clock import Clock
import datetime
class MyFloat(FloatLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.label = Label()
self.add_widget(self.label)
self.task = Clock.schedule_interval(self.update_label, 0.1)
def update_label(self, dt):
now = datetime.datetime.now()
self.label.text = now.strftime("%Y.%m.%d %H:%M.%S")
class MyApp(App):
def build(self):
return MyFloat()
if __name__ == "__main__":
MyApp().run()
顺便提一句:
当您必须运行长时间运行的代码时,您可能需要multiprocessing
/ 。threading
但它可能还需要Queue
与主进程通信。通常 GUI 不能修改分离的进程/线程中的小部件。
推荐阅读
- asp.net - Bootstrap Modal Popup Not Clearing old value ASP.NET
- c - 用指针打印字符的问题
- linux-kernel - 通过流式 DMA 映射对主存储器进行非相干访问
- python - 不知道如何为 Naoqi python-sdk 设置 PYTHONPATH 变量
- delphi - Techart,由于标题更改而自动重新计算自定义标记区域
- sqlite - SQLITE:如何将 rowid 列转换为常规列
- python - 蟒蛇滚动3个骰子
- logging - 努力对 Moodle 数据库表“mdl_logstore_standard_log”进行正确查询,以便从 GUI 中导出日志
- spring - 春季批处理重试不适用于重试模板
- cordova - 错误运行子进程cordova时发生错误