запуск Popup.dismiss () в методе, который не вызывал Popup.open () (kivy) - PullRequest
0 голосов
/ 28 июня 2019

Я пытаюсь разработать приложение kivy для моих менее опытных коллег, которое использует приятный графический интерфейс для некоторых вычислений, которые я разработал для проекта;в настоящее время у меня есть два метода, встроенных в класс, один (называемый «фиктивным»), который защищает графический интерфейс от зависания, и второй многопоточный метод (называемый «вычислить»), который фактически выполняет вычисления.В рамках фиктивного метода я надеюсь открыть всплывающее окно, которое отображает «загрузочный GIF» (что указывает на то, что программа работает, а не просто заморожена), и я хочу, чтобы всплывающее окно закрывалось после завершения метода «вычисления».Как привязать автоматическое закрытие всплывающего окна к завершению метода вычисления (self, * args)?

- GUI.py -

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
import threading
from calc import main


class Pop(Popup):
    pass


class MetaLevel(GridLayout):
    def dummy(self, *args):
        Pop().open()
        threading.Thread(target=self.calculate, args=(args,)).start()

    def calculate(self, *args):
        main()


class graphics(App):
    def build(self):
        return MetaLevel()


if __name__ == "__main__":
    graphics().run()

- calc.py -

def main():
    import numpy as np
    from pathos.multiprocessing import ProcessPool as Pool

    grid = np.array([(m, n)
                     for m in np.arange(1, 100, 1)
                     for n in np.arange(1, 100, 1)])

    def calc(grid):
        var1 = grid[0]
        var2 = grid[1]
        y = var1*var2
        return y

    res = Pool().map(calc, grid)
    print('done')
    # data output from res here

- graphics.kv -

<Button>:
    font_size: 12

<MetaLevel>:
    id: calculator
    rows: 5
    padding: 10
    spacing: 10

    BoxLayout:
        height: 10
        Label:
            spacing: 10
            text: 'test'

    BoxLayout:
        Button:
            id: run_button
            text: "Run"
            on_release: root.dummy()

--- Редактировать 1 ---

Все еще работаетпри попытке решить проблему;Я наткнулся на функцию Clock.create_trigger () и попытался интегрировать ее в класс Pop - проблема в том, что я не могу понять, как вызывать trigger () после main () в методе вычисления (см. Ниже).Может быть жизнеспособным решением проблемы, если мы сможем запустить триггер.

- GUI.py -


from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
import threading
from kivy.clock import Clock
from calc import main


class Pop(Popup):
    def __init__(self, **kwargs):
        super(Pop, self).__init__(**kwargs)
        trigger = Clock.create_trigger(self.dismiss_popup)

    def dismiss_popup(self, dt):
        self.dismiss()


class MetaLevel(GridLayout):
    def dummy(self, *args):
        Pop().open()
        threading.Thread(target=self.calculate, args=(args,)).start()

    def calculate(self, *args):
        main()
        trigger() # after main finishes I want to toggle the trigger, but kivy/python doesn't like this



class graphics(App):
    def build(self):
        return MetaLevel()


if __name__ == "__main__":
    graphics().run()

1 Ответ

1 голос
/ 29 июня 2019

Попробуйте назначить ваше всплывающее окно переменной в вашем классе, которая наследуется от App (я назову это вашим "основным классом приложения").Вы можете ссылаться на переменные и функции из вашего основного класса приложения, используя App.get_running_app().your_variable в Python или просто app.your_variable в языке kv.

В вашем случае удалите строку в GUI.py Pop().open() и замените ее следующей строкой:

App.get_running_app().pop.open()

Затем в своем классе graphics создайте переменную длянеожиданно возникнуть.Вы можете сделать это в функции build, просто добавив self.pop = Pop()

Теперь в вашей программе calc.py вам нужно будет добавить from kivy.app import App, затем в конце вашей функции mainдобавьте строку, чтобы закрыть всплывающее окно:

App.get_running_app().pop.dismiss()

...