如何在kivy中显示和删除图像?
Posted
技术标签:
【中文标题】如何在kivy中显示和删除图像?【英文标题】:How to display and remove an Image in kivy? 【发布时间】:2021-02-25 12:01:52 【问题描述】:我已经找了两个小时的答案了。我想在 kivy 中完成的是:
import time
clear = "\033[2J\033[1;1f"
print("""
################################
##this should display an image##
################################""")
time.sleep(1)
print(clear)
print("""
#####################################
##this should display another image##
#####################################""")
这是我已经准备好的程序的开始,但不像 kivy 那样作为真正的桌面应用程序。
程序以显示图像开始,暂停一秒钟,然后在使用按钮等启动主菜单之前不显示图像(不重要)。
这是我目前所拥有的(不工作):
class Intro(FloatLayout):
connection = Image(source='connection.png')
noconnection = Image(source='noconnection.png')
checkloop = True
def check_connection(self, dt):
url='http://www.google.com/'
timeout=5
connected.stop()
noconnection.stop()
try:
server = smtplib.SMTP('smtp.gmail.com', 587)
_ = requests.get(url, timeout=timeout)
connected.play()
self.add_widget(self.connection)
Clock.schedule_once(self.remove_widget(self.connection), 1)
checkloop = False
except requests.ConnectionError:
noconnection.play()
self.add_widget(self.noconnection)
self.remove_widget(self.noconnection)
txtinput = TextInput(text='ConnectionError. Enter to try again...')
except smtplib.SMTPConnectError:
noconnection.play()
img = Image(source='noconnection.png')
self.add_widget(self.noconnection)
self.remove_widget(self.noconnection)
txtinput = TextInput(text='SMTPConnectError. Enter to try again...')
class I41(App):
def build(self):
self.icon = 'riseicon.png'
self.title = '41'
intro = Intro()
Clock.schedule_once(intro.check_connection)
print("DONE")
我到底做错了什么?
我希望你们能帮助我!在 *** 上提出的第一个问题!
【问题讨论】:
您不能将 time.sleep(1) 与 Kivy 一起使用,因为它会阻塞并导致应用程序挂起。您必须使用 kivy.clock 设置计时器。看看这个kivy.org/doc/stable/api-kivy.clock.html。 您可以在 Kivy 中使用 time.sleep,它只是不能满足您的需求,而使用 Clock.schedule_once 是一个合适的解决方案。 另外,您的return
s 没有意义 - 该函数在遇到第一个值时会立即返回一个值,以后的任何值都将永远无法达到。
【参考方案1】:
在您的 check_connection()
方法中,您有许多 return
语句。请注意documentation。说:
return 离开当前函数
因此遇到返回后的任何内容都不会被执行,并且方法中的任何其他代码都将停止(如while
循环)。
解决方法是使用对 Clock.schedle_once()
的调用来调用要在 return
之后执行的代码。
下面是一个简单的例子:
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
class MyFloatLayout(FloatLayout):
img = Image(source='connection.png')
checkloop = True
def showImage(self, dt):
self.add_widget(self.img)
# other code here, like connecting to Google
if self.checkloop:
# continue loop
Clock.schedule_once(self.deleteImage, 1)
def deleteImage(self, dt):
self.remove_widget(self.img)
if self.checkloop:
# continue loop
Clock.schedule_once(self.showImage, 1)
class I41(App):
def build(self):
self.icon = 'riseicon.png'
self.title = '41'
root = MyFloatLayout()
# start image loop
Clock.schedule_once(root.showImage)
return root
I41().run()
通过在MyFloatLayout
中将checkloop
设置为False
来停止循环。
【讨论】:
感谢您的帮助!我编辑了我的代码,但它仍然无法正常工作......我仍然做错了什么?没有错误出现,只是没有图片显示和声音播放...... 您仍在使用time.sleep()
。当您在主线程上运行一个方法时,就像您的 check_connection()
一样,在该方法完成之前,GUI 无法更新。 check_connection()
方法向 GUI 添加一个小部件,休眠 2 秒,删除该小部件,然后返回。返回后,App 重新获得对主线程的访问权限并更新 GUI,当时还没有 connection
小部件。仔细看看我的答案,使用Clock.schedule_once()
完成延迟。
我将 time.sleep 换成了 Clock.schedule_once ...仍然没有任何反应...我现在做错了什么?
在您的Clock.schedule_once
中使用self.remove_widget(self.connection)
。该代码立即删除connection
小部件,然后安排调用该方法的返回(即None
)。尝试使用Clock.schedule_once(partial(self.remove_widget, self.connection), 1)
,它使用参数self.connection
安排对self.remove_widget
的调用。
知道了!作品!谢谢!以上是关于如何在kivy中显示和删除图像?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Kivy 的 Scrollable GridLayout 中显示图像