我有一些文本在输出上有点连续(有些=在实际应用程序中每两秒左右)。
当只有print
进入终端时,无论我保持运行循环多长时间,一切都还可以。
然而,当将打印引导到wx
帧时,打印动作本身就很顺利,这里没问题,但是如果我保持运行循环超过10-20个循环,我将无法再关闭通常的窗口(在此示例中为鼠标或Ctrl + F4,但如果我构造一个显式的Exit事件菜单,则相同)。线程中的操作停止,但应用程序挂起 - 它只能由操作系统(在我的情况下为Windows)关闭,并强制关闭/等待程序响应"对话。但是,当终端窗口处于焦点时,可以使用Ctrl + C立即关闭它。看起来有些东西填满了过多的文字并锁定了结束过程。
在多行WriteText
窗口中使用AppendText
或wxTextCtrl
,或在下面的测试代码中使用SetLabel。
在此测试中,如果我在发射后几乎立即关闭wx窗口,它会很好地关闭。如果我继续运行循环更长时间(或通过注释掉两个time.sleep()
行),那么只要尝试关闭窗口,挂起就会成功。
我在这里缺少什么? (我有什么必须冲洗吗?)
编辑嗯,这个问题可能与"线程安全方法"有关,如简要描述here。将在这个方向上做一些测试,必须找出每个wx.CallAfter
,wx.CallLater
或wx.PostEvent
的正确用法。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import wx
import time
import threading
class TestFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.sometext = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_READONLY)
self.thread = None
self.alive = threading.Event()
self.__set_properties()
self.__do_layout()
self.__attach_events()
self.StartThread()
def __set_properties(self):
self.SetTitle("test")
def __do_layout(self):
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.sometext, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
self.SetSizer(sizer)
sizer.Fit(self)
self.Layout()
def __attach_events(self):
self.Bind(wx.EVT_CLOSE, self.OnClose)
def OnClose(self, event):
""" stop & close on system window close """
self.StopThread()
self.Destroy()
def StartThread(self):
""" start the thread """
self.thread = threading.Thread(target=self.TestThread)
self.thread.setDaemon(1)
self.alive.set()
self.thread.start()
def StopThread(self):
""" stop the thread, wait util it is finished """
if self.thread is not None:
self.alive.clear()
self.thread.join()
self.thread = None
def TestThread(self):
""" main thread """
while self.alive.isSet():
self.sometext.SetLabel("Hello")
time.sleep(0.5)
self.sometext.SetLabel("Python")
time.sleep(0.5)
class MyApp(wx.App):
def OnInit(self):
wx.InitAllImageHandlers()
frame = TestFrame(None, -1, "")
self.SetTopWindow(frame)
frame.Show(1)
return 1
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()
答案 0 :(得分:0)
我已使用AppendtText更改了每个SetLabal。我不知道为什么,但SetLabel功能对我来说无法正常工作。
几秒钟后,应用程序将停止工作。这是我的错误输出:
(python:14099): Pango-CRITICAL **: pango_layout_get_iter: assertion 'PANGO_IS_LAYOUT (layout)' failed
Segmentation fault
之后我使用了CallAfter函数http://wiki.wxpython.org/CallAfter,应用程序开始正常为我工作。我的TestThread版本:
def TestThread(self):
""" main thread """
while self.alive.isSet():
wx.CallAfter(self.sometext.AppendText, "Hello")
time.sleep(0.5)
wx.CallAfter(self.sometext.AppendText, "Python")
time.sleep(0.5)
wx.CallAfter(self.sometext.Clear)
我希望这对你有所帮助。