SetValue 上的 wxpython TextCtrl 分段错误
wxpython TextCtrl segmentation fault on SetValue
我正在使用 wxglade 构建一个小应用程序。
它基本上只是一个 TextCtrl 多行和只读。
我启动一个读取文件并将内容显示到 TextCtrl 中的线程。
经过一系列执行后,我得到了一个分段错误。
Debian 9
Python 3.5.3
wxpython 4.0.7.post2
有什么建议吗?
非常感谢!
代码
import wx, threading, pdb
import gettext
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.text_ctrl_1 = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.__set_properties()
self.__do_layout()
self.update_text()
def update_text(self):
print("update_text")
text = ""
try:
f = open("test.txt", "r")
text = f.read()
f.close()
except:
print(_('Error opening test.txt file!'))
text = _('Error opening test.txt file!')
self.text_ctrl_1.SetValue(text)
threading.Timer(1, self.update_text).start()
def __set_properties(self):
self.SetTitle(_("frame"))
def __do_layout(self):
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(self.text_ctrl_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == "__main__":
gettext.install("app") # replace with the appropriate catalog name
app = MyApp(0)
app.MainLoop()
错误
update_text
update_text
update_text
update_text
(wxglade_out.py:5127): Gtk-WARNING **: Invalid text buffer iterator:
either the iterator is uninitialized, or the
characters/pixbufs/widgets in the buffer have been modified since the
iterator was created. You must use marks, character numbers, or line
numbers to preserve a position across buffer modifications. You can
apply tags and insert marks without invalidating your iterators, but
any mutation that affects 'indexable' buffer contents (contents that
can be referred to by character offset) will invalidate all
outstanding iterators
(wxglade_out.py:5127): Gtk-WARNING **: Invalid text buffer iterator:
either the iterator is uninitialized, or the
characters/pixbufs/widgets in the buffer have been modified since the
iterator was created. You must use marks, character numbers, or line
numbers to preserve a position across buffer modifications. You can
apply tags and insert marks without invalidating your iterators, but
any mutation that affects 'indexable' buffer contents (contents that
can be referred to by character offset) will invalidate all
outstanding iterators Segmentation fault
我认为从线程内更新不会正常工作。
应使用主 GUI 循环执行更新。
我不知道这是否与 gtk 相关:Gtk +3 TextView application crashes
您可以尝试通过 pubsub 更新,您自己的一些设备使用变量或使用 wx.Timer
而不是线程,即
import wx
import time
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.text_ctrl_1 = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.__set_properties()
self.__do_layout()
#self.update_text(None)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.update_text, self.timer)
self.timer.Start(5000)
def update_text(self, event):
print("update_text")
self.text_ctrl_1.Clear()
wx.GetApp().Yield() # to see the clear occur release momentarily to the main loop
try:
with open("test.txt", "r") as f:
text = f.read()
except:
print(_('Error opening test.txt file!'))
text = _('Error opening test.txt file!')
time.sleep(2)
self.text_ctrl_1.SetValue(text)
def __set_properties(self):
self.SetTitle("My frame")
def __do_layout(self):
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(self.text_ctrl_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == "__main__":
app = MyApp()
app.MainLoop()
我正在使用 wxglade 构建一个小应用程序。
它基本上只是一个 TextCtrl 多行和只读。 我启动一个读取文件并将内容显示到 TextCtrl 中的线程。 经过一系列执行后,我得到了一个分段错误。
Debian 9 Python 3.5.3 wxpython 4.0.7.post2
有什么建议吗? 非常感谢!
代码
import wx, threading, pdb
import gettext
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.text_ctrl_1 = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.__set_properties()
self.__do_layout()
self.update_text()
def update_text(self):
print("update_text")
text = ""
try:
f = open("test.txt", "r")
text = f.read()
f.close()
except:
print(_('Error opening test.txt file!'))
text = _('Error opening test.txt file!')
self.text_ctrl_1.SetValue(text)
threading.Timer(1, self.update_text).start()
def __set_properties(self):
self.SetTitle(_("frame"))
def __do_layout(self):
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(self.text_ctrl_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == "__main__":
gettext.install("app") # replace with the appropriate catalog name
app = MyApp(0)
app.MainLoop()
错误
update_text update_text update_text update_text
(wxglade_out.py:5127): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created. You must use marks, character numbers, or line numbers to preserve a position across buffer modifications. You can apply tags and insert marks without invalidating your iterators, but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset) will invalidate all outstanding iterators
(wxglade_out.py:5127): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created. You must use marks, character numbers, or line numbers to preserve a position across buffer modifications. You can apply tags and insert marks without invalidating your iterators, but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset) will invalidate all outstanding iterators Segmentation fault
我认为从线程内更新不会正常工作。
应使用主 GUI 循环执行更新。
我不知道这是否与 gtk 相关:Gtk +3 TextView application crashes
您可以尝试通过 pubsub 更新,您自己的一些设备使用变量或使用 wx.Timer
而不是线程,即
import wx
import time
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.text_ctrl_1 = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
self.__set_properties()
self.__do_layout()
#self.update_text(None)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.update_text, self.timer)
self.timer.Start(5000)
def update_text(self, event):
print("update_text")
self.text_ctrl_1.Clear()
wx.GetApp().Yield() # to see the clear occur release momentarily to the main loop
try:
with open("test.txt", "r") as f:
text = f.read()
except:
print(_('Error opening test.txt file!'))
text = _('Error opening test.txt file!')
time.sleep(2)
self.text_ctrl_1.SetValue(text)
def __set_properties(self):
self.SetTitle("My frame")
def __do_layout(self):
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(self.text_ctrl_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == "__main__":
app = MyApp()
app.MainLoop()