@Only4You

Как запустить функцию в отдельном потоке второй раз?

Набросал простенький макет, дабы понять как работает многопоточность и применять в будущем для функций с циклами while и sleep(), не тормозящими всю остальную программу:
from tkinter import *
from tkinter import ttk
import threading
from datetime import datetime

date = datetime.now()
i = 0
y = 0

def start():
    global i
    i = 0
    thr1.start()

def stop():
    global i
    i = 500
    print(f'i = {i}')

def ex1():
    date = datetime.now()
    global i, lbl1
    while i < 500:
        print(f'i = {i}')
        i += 1
        time.sleep(3)
    else:
        print('Exit')
    date_last = datetime.now()
    # print(date)
    print(date_last - date)

thr1 = threading.Thread(target=ex1)

root = Tk()
root.geometry()

btn1 = ttk.Button(text='Start', command=start)
btn1.pack()
btn2 = ttk.Button(text='Stop', command=stop)
btn2.pack()

root.mainloop()


При запуске и нажатии кнопки старт функция выполняется, и кнопки основного окна не блокируются. То что нужно.
Но в дальнейшем, если к примеру while сделать False и остановить цикл, после повторной попытки запустить эту функцию, питон выбрасывает
"RuntimeError: threads can only be started once"
Можно ли это как-то обойти понятным для начинающего в python способом?
Может пока без многопоточности, но чтоб приложение не блокировалось при выполнении функции в бесконечном цикле?
Пы.сы И еще вопрос. в коде видно, чтоб запустить функци с отдельным потоком с кнопки Ткинтера, пришлось создавать функцию start(), и привязывать её к command= которая его запускает. Может можно как-то по-другому стартовать, без доп функции?
  • Вопрос задан
  • 95 просмотров
Решения вопроса 3
@LanskoyGames
У модераторов первое место, но только с конца...
Может лучше асинхрнность(в Python - async), там и прерывание, возобновление, создание новых, асинхронных задач
Ответ написан
@Everything_is_bad
Как запустить функцию в отдельном потоке второй раз?
надо всего лишь создавать поток именно в том месте, где его запускаешь
Ответ написан
Vindicar
@Vindicar
RTFM!
1.
"RuntimeError: threads can only be started once"
Можно ли это как-то обойти понятным для начинающего в python способом?

Можно перестать хотеть странного и принять как данность, что завершившийся поток - завершился. С ним уже ничего не сделаешь. Это так на уровне ОС, если что. Так что создавай экземпляр Thread тогда, когда надо запустить поток.
2.
Может можно как-то по-другому стартовать, без доп функции?

И как ты это себе представляешь? Tkinter должен знать, какой твой код выполнить при нажатии кнопки. Единственный способ это сделать - передать ему функцию или иной callable object. Да, можно использовать лямбду, но в лямбду много не уместишь, так что лучше функция.
А когда придёшь к оборачиванию GUI в классы, поймёшь, что передача функции/метода - наиболее простой и практичный подход.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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