Как заменить виджеты Kivy на обратный вызов?

WaitForInputIdle работает, но не так, как вы предполагаете. Это в значительной степени связано с тем, что документация вводит в заблуждение (или, по крайней мере, не так явно, как она должна быть):

Ожидает, что указанный процесс завершит обработку своего исходного ввода и ожидает ввода пользователем с нет ожидающего ввода или до истечения интервала времени ожидания.

blockquote>

Это почти уголовно неточно. В разделе Примечания отмечается, что WaitForInputIdle ждет не более одного раза за процесс, он никогда не упоминает важные детали. В частности:

  • WaitForInputIdle возвращает, как только начальный запуск переместился в точку, где любой поток процесса готов к обработке сообщений. Эти сообщения не обязательно должны вводиться пользователем.
  • WaitForInputIdle был изобретен, чтобы позволить процессу связываться с дочерним процессом с использованием протокола на основе сообщений. В качестве конкретного сценария использовался DDE , который больше не используется 1).

WaitForInputIdle не может использоваться как надежное решение вашей проблемы: Ожидание ребенка процесса ". Вам действительно нужно дождаться появления пользовательского интерфейса.

Система предлагает два решения, которые вы можете использовать:

  1. Глобальный CBT hook и дождитесь обратного вызова HCBT_CREATEWND. Вы можете проверить член CREATESTRUCT lpszClass и / или lpszName , чтобы отфильтровать интересующее вас окно.
  2. Используйте WinEvents и ответьте на событие EVENT_OBJECT_CREATE .

Вызывается глобальный крючок CBT, когда окно приближается к быть создан. Структуры ядра, в которых ссылки HWND были полностью заполнены, но клиентский вызов CreateWindow[Ex] может по-прежнему прекращать создание окна. В отличие от этого, WinEvent выдается после того, как окно полностью построено и готово к взаимодействию.

В общем, решение, основанное на крюке CBT, используется, когда приложение должно обновлять некоторые аспекты окна перед тем, как вызывающий абонент CreateWindowEx впервые увидит HWND. WinEvents, как правило, являются инструментом выбора при реализации решений для обеспечения доступности или автоматизации пользовательского интерфейса.

Дополнительные ресурсы:

1) Да, я знаю , некоторые приложения могут использовать DDE. Но если Раймонд Чен предложил в 2007 году, что мы должны перестать использовать DDE , я просто передам это как авторитетное руководство.

0
задан Tyler Joseph 5 April 2019 в 14:33
поделиться

1 ответ

Вот простое решение вашей проблемы. Я оставлю это вам, чтобы изменить и сделать так, чтобы он выглядел и работал именно так, как вы хотите:)

Изучение языка kv НЕВЕРОЯТНО полезно, легко и его можно довольно быстро освоить.

main.py

from kivy.app import App

class MainApp(App):
    alphabet = 'abcdefghijklmnopqrstuvwxyz'

    def next_letter(self):
        # Get a reference to the widget that shows the letters
        # self.root refers to the root widget of the kv file -- in this case,
        # the GridLayout
        current_letter_widget = self.root.ids['the_letter_label']
        # Get the letter currently shown
        current_letter = current_letter_widget.text
        # Find the next letter in the alphabet
        next_letter_index = self.alphabet.find(current_letter) + 1
        next_letter = self.alphabet[next_letter_index]

        # Set the new letter in the widget that shows the letters
        current_letter_widget.text = next_letter

MainApp().run()

main.kv

GridLayout: # This is the `root` widget of the main app class
    cols: 1
    Label:
        text: "g"
        id: the_letter_label # Setting an id for a widget lets you refer to it later
    Button:
        text: "Previous"
    Button:
        text: "Next"
        on_release:
            # the keyword `app` references the main app class, so we can call
            # the `next_letter` function
            app.next_letter()

Я с удовольствием отвечу на конкретные вопросы, если они у вас есть.

0
ответ дан Erik 5 April 2019 в 14:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: