Сбой многопоточного скрипта Tkinter при создании второго виджета Toplevel

у меня есть скрипт Python, который использует Tkinter для GUI. Мой маленький скрипт должен создавать виджет Toplevel каждые X секунд. Когда я запускаю свой код, первый виджет Toplevel создан успешно, но когда он пытается создать второй, программа вылетает.

Что я делаю, так это использую метод after для вызова функции startCounting каждые 5 секунд вместе с основной цепью root. Каждый раз, когда вызывается эта функция, я добавляю объект виджета Toplevel в список и запускаю новый поток, который, будем надеяться, будет запускать новый основной цикл.

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

Код:

import threading,thread
from Tkinter import *


def startCounting():
    global root
    global topLevelList
    global classInstance

    topLevelList.append (Toplevel())
    topLevelList[len(topLevelList)-1].title("Child")
    classInstance.append(mainLoopThread(topLevelList[len(topLevelList)-1]))

    root.after(5000,startCounting)


class mainLoopThread(threading.Thread):
    def __init__(self,toplevelW):
        self.toplevelW = toplevelW
        threading.Thread.__init__(self)
        self.start()
    def run(self):
        self.toplevelW.mainloop()



global classInstance
classInstance = []
global topLevelList
topLevelList = []
global root

root = Tk() 
root.title("Main")
startCounting()
root.mainloop()
8
задан tshepang 31 July 2014 в 08:58
поделиться

2 ответа

только из основного потока. См. документацию:

Просто запустите весь код пользовательского интерфейса в главном поток, и пусть писатели пишут в объект очереди; например

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

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

Правильная архитектура Python для этой проблемы всегда состоит в том, чтобы выделить поток (основной, если он необходим) для обслуживания привередливого объекта или подсистемы; каждый другой поток, требующий взаимодействия с указанной подсистемой или объектом, должен получить его, поставив в очередь запросы к выделенному потоку (и, возможно, ожидая результатов в «очереди возврата», если результаты требуются как следствие какого-либо запроса). Это также очень надежная архитектура Python для многопоточности общего назначения (и я подробно излагаю ее в "Python в двух словах", но это уже другая тема ;-).

24
ответ дан 3 November 2019 в 13:35
поделиться

Есть ли причина, по которой вы хотите (или думаете, что вам нужен) один цикл обработки событий для каждого окна верхнего уровня? Один цикл событий может обрабатывать десятки (если не сотни или тысячи) окон верхнего уровня. И, как было указано в другом ответе, вы не можете запустить этот цикл событий в отдельном потоке.

Итак, чтобы исправить свой код, вам нужно использовать только один цикл обработки событий и запускать его в основном потоке.

0
ответ дан 3 November 2019 в 13:35
поделиться
Другие вопросы по тегам:

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