Как отобразить и удалить изображение в kivy?

#python #image #kivy

#python #изображение #kivy

Вопрос:

Я искал ответ уже два часа. Чего я пытаюсь достичь в kivy, так это:

 import time
clear      = "33[2J33[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")
  

Что я все еще делаю не так?

Я надеюсь, что вы, ребята, сможете мне помочь! Первые вопросы, заданные в stackoverflow!

Комментарии:

1. Вы не можете использовать time.sleep(1) с Kivy, потому что это блокирует и приведет к зависанию приложения. Вы должны установить таймер с помощью kivy.clock. Взгляните на это kivy.org/doc/stable/api-kivy.clock.html .

2. Вы можете использовать time.sleep с Kivy, он просто не делает то, что вы хотите, и использование Clock.schedule_once является подходящим решением.

3. Также ваши return s не имеют смысла — функция возвращает значения, как только она попадает в первое, все последующие значения никогда не будут достигнуты.

Ответ №1:

В вашем check_connection() методе у вас много return операторов. Обратите внимание, что документация. говорит:

return оставляет текущую функцию

Таким образом, все, что встречается после возврата, не будет выполнено, и любой другой код в методе будет остановлен (например while , цикл).

Исправление заключается в вызове кода, который вы хотите выполнить после return использования вызова Clock.schedle_once() .

Вот простой пример того, как это сделать:

 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()
  

Цикл останавливается, если установить значение checkloop False in MyFloatLayout .

Комментарии:

1. Спасибо за помощь! Я отредактировал свой код, но он все еще не работает… Что я все еще делаю не так? Ошибок не возникает, просто не отображаются изображения и не воспроизводится звук…

2. Вы все еще используете time.sleep() . Когда вы запускаете метод в основном потоке, как ваш check_connection() , графический интерфейс не может обновляться до завершения этого метода. check_connection() Метод добавляет виджет в графический интерфейс, спит в течение 2 секунд, удаляет этот виджет, затем возвращается. После возврата приложение восстанавливает доступ к основному потоку и обновляет графический интерфейс, в котором на тот момент нет connection виджета. Более внимательно посмотрите на мой ответ, где задержки выполняются с помощью Clock.schedule_once() .

3. Я заменил time.sleep на Clock.schedule_once … по-прежнему ничего не происходит… Что я сейчас делаю не так?

4. В вашем Clock.schedule_once вы используете self.remove_widget(self.connection) . Этот код connection немедленно удаляет виджет, а затем планирует вызов возврата этого метода (который есть None ). Попробуйте использовать Clock.schedule_once(partial(self.remove_widget, self.connection), 1) , который запланирует вызов self.remove_widget с аргументом self.connection .

5. Понял! Работает! Спасибо!