Ваша проблема на самом деле не имеет ничего общего с потоками и графическим интерфейсом. Вы всегда должны использовать Twisted и GTK из одного потока: в противном случае нет необходимости.
Ваша проблема в том, что вы используете gtk.Dialog.run()
. Это API, который вы никогда не должны использовать, Twisted или нет. Он запускает повторяющийся основной цикл, который вызывает блокировку текущего обработчика событий, но позволяет другим обработчикам событий выполнять один уровень вниз по стеку. GTK имеет отличную поддержку для повторных входных главных циклов, но Twisted нет (и это нормально, потому что, как я уже сказал, вы не должны их использовать).
MessageDialog.run не будет работать в потоке, так что у вас фактически нет этой опции. Это приведет к непредсказуемому поведению, которое может привести к тому, что ваше приложение будет вести себя странно или зависать. GTK прекрасно поддерживает потоки, но есть вещи, которые вы никогда не должны делать с потоками, потому что это не имеет никакого смысла, и это один из них.
Если вы имеете дело с кодом, который не выполняет никакой обработки, но просто хочет дождаться, чтобы что-то произошло (например, ожидание нажатия пользователем кнопки в диалоговом окне), вам следует использовать функции, которые возвращают Deferred
с, а не темы. Как это происходит, gtk.Dialog
s будет излучать сигнал в точке, на которую они отвечают: "response
". Вы можете использовать это, чтобы подключить очень простую функцию, которая отображает ваше сообщение с диалоговым окном и возвращает Deferred
после его завершения. Вот пример:
def showMessage(text):
mdlg = gtk.MessageDialog(type=gtk.MESSAGE_INFO,
buttons=gtk.BUTTONS_CLOSE,
message_format=text)
result = Deferred()
def response(dialog, response_id):
mdlg.destroy()
result.callback(response_id)
return False
mdlg.connect("response", response)
mdlg.show_all()
return result