Ткинтер и мультипроцессинг - PullRequest
0 голосов
/ 01 мая 2019

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

В первом модуле:

tkinterModule.initialize(functionFromMainModule)

Во втором модуле:

...
button = Button(master, 
                 text="Launch Function", 
                 command=partial(play, callback))

def play(callback=None):
     if callback is not None:
         callback()

Тогда в первом модуле:

def functionFromMainModule():
    ....
    if __name__ == '__main__':
        p = multiprocessing.Process(target=longFunction)
        p.start()

def longFunction():
    ...

Но вместо запуска longFunction он просто повторно инициализирует новый холст tkinter и не запускает функцию. Если я просто вызываю функцию и не использую многопроцессорность, то функция вызывается нормально (но tkinter блокируется до конца выполнения).

Ответы [ 2 ]

1 голос
/ 01 мая 2019

Ну, я полагаю, что вы работаете в Windows, поэтому ваша проблема в том, что когда запускается новый процесс, Python pickle обрабатывает весь код в вашем модуле (или пакете) (это связано с ограничениями Windows )

Итак, когда вы используете многопроцессорный модуль, вы должны использовать оператор if __name__ == '__main__':.Вот объяснение, почему:

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

0 голосов
/ 01 мая 2019

Возможное решение этой проблемы - использование потоков.В Python есть модуль под названием Threading.Вы можете использовать этот модуль для создания потоков, чтобы ваше приложение tkinter не зависало.Вот как это выглядит.

import threading

def Function(Data):
   print(Data)

thread = threading.Thread(target=Function, args=["Hi"], daemon=True).start()

# daemon simply means that the thread will die once done executing.

Мы создаем поток с именем thread.Поток выполнит функцию.Потоки делят программу на одновременно выполняемые задачи.Что, другими словами, означает, что две или более задач могут быть выполнены в одно и то же время.Потоки в одном и том же процессе используют одну и ту же память и ресурсы, а процесс - нет.Вы также можете создавать потоки в классах, используя модуль потоков.Просто импортируйте модуль потоков и наследуйте его в классе.Например,

import threading

class Animal(threading.Thread):
    def __init__(self, v):

        threading.Thread.__init__(self, Variable):  # init for threaded classes
        self.Variable = Variable
        self.Run()
    def Run(self):
        print("I am an animal")


A = Animal("Snake")

A.start()

Это замечательно, если вы хотите, чтобы объект работал, не замедляя работу приложения и не вызывая его зависание и зависание.

...