wxpython TextCtrl在SetValue上出现分段错误
我正在用wxglade构建一个小应用程序 它基本上只是一个TextCtrl多行且只读。 我启动一个线程来读取文件并将内容显示到TextCtrl中。 在一系列执行之后,我得到了一个分段错误 Debian 9 Python 3.5.3 wxpython 4.0.7.post2 有什么建议吗? 非常感谢 代码wxpython TextCtrl在SetValue上出现分段错误,python,wxpython,Python,Wxpython,我正在用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,
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()
错误
更新文本
更新文本
更新文本
更新文本
(wxglade_out.py:5127):Gtk警告**:无效的文本缓冲区迭代器:
迭代器未初始化,或者
自
迭代器已创建。必须使用标记、字符号或线条
在缓冲区修改中保留位置的数字。你可以
在不使迭代器无效的情况下应用标记和插入标记,但是
影响“可索引”缓冲区内容的任何变异
可由字符偏移量引用)将使所有
优秀迭代器
(wxglade_out.py:5127):Gtk警告**:无效的文本缓冲区迭代器:
迭代器未初始化,或者
自
迭代器已创建。必须使用标记、字符号或线条
在缓冲区修改中保留位置的数字。你可以
在不使迭代器无效的情况下应用标记和插入标记,但是
影响“可索引”缓冲区内容的任何变异
可由字符偏移量引用)将使所有
突出迭代器分段错误
我不相信从线程内进行更新会正常工作。
应使用主GUI循环执行更新。
我不知道这是否与gtk有关: 您可以通过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()
谢谢,我想你找到问题了!