Хорошо, так что мне удалось отследить проблему. Мне никогда не удавалось воссоздать эту проблему в Mac OS X 10.5.8, где я изначально разрабатывал код. Кажется, что ошибки сегментации возникают только в RedHat Enterprise Linux 5.
Оказывается, этот кусок кода является виновником:
def write(self,val,is_stderr=False):
#Fun Fact: The way Tkinter Text objects work is that if they're disabled,
#you can't write into them AT ALL (via the GUI or programatically). Since we want them
#disabled for the user, we have to set them to NORMAL (a.k.a. ENABLED), write to them,
#then set their state back to DISABLED.
self.write_lock.acquire()
self.config(state=tk.NORMAL)
self.insert('end',val,'STDERR' if is_stderr else 'STDOUT')
self.see('end')
self.config(state=tk.DISABLED)
self.write_lock.release()
Хотелось бы, чтобы у меня было объяснение , почему происходят ошибки сегментации, но я обнаружил, что постоянное включение и отключение объекта Text является виновником. Если я изменю вышеуказанный кусок кода на это:
def write(self,val,is_stderr=False):
self.write_lock.acquire()
self.insert('end',val,'STDERR' if is_stderr else 'STDOUT')
self.see('end')
self.write_lock.release()
Мои ошибки сегментации исчезают, когда я удаляю вызовы self.config(state=...)
. Весь смысл вызовов self.config(state=...)
состоял в том, чтобы пользователь не мог редактировать текстовое поле. Когда текстовое поле находится в состоянии tk.DISABLED
, вызовы self.insert(...)
также не работают.
Обходное решение, которое я придумала, состоит в том, чтобы оставить поле «Текст» включенным, но заставить поле «Текст» игнорировать весь ввод с клавиатуры (создавая иллюзию поведения только для чтения, если пользователь пытается использовать клавиатуру). Самый простой способ сделать это - изменить метод __init__
, чтобы он выглядел следующим образом (измените состояние на tk.NORMAL
и измените привязку для событий <Key>
):
def __init__(self, master=None, cnf={}, **kw):
'''See the __init__ for Tkinter.Text for most of this stuff.'''
tk.Text.__init__(self, master, cnf, **kw)
self.started = False
self.write_lock = threading.Lock()
self.tag_configure('STDOUT',background='white',foreground='black')
self.tag_configure('STDERR',background='white',foreground='red')
self.config(state=tk.NORMAL)
self.bind('<Key>',lambda e: 'break') #ignore all key presses
Надеюсь, это поможет любому, кто столкнется с той же проблемой.