4

在这个程序中,当我在线程中使用 while True 循环时出现错误。没有循环,我不会出错。当然,在实际程序中,我不会连续更新标签。知道我做错了什么吗?

这是程序:

import wx
import thread

class Example(wx.Frame):

    def __init__(self, parent): 
        wx.Frame.__init__(self,parent)
        self.InitUI()

    def InitUI(self):
        self.SetSize((250, 200))
        self.Show(True)

        self.text = wx.StaticText(self, label='',pos=(20,30))

        thread.start_new_thread(self.watch,(self,None))

    def watch(self,dummy,e):
        while True:
            self.text.SetLabel('Closed')


def main():
    ex = wx.App()
    Example(None)
    ex.MainLoop()    

if __name__ == '__main__':
    main() 

这是错误:

Pango:ERROR:/build/pango1.0-LVHqeM/pango1.0-1.30.0/./pango/pango-            layout.c:3801:pango_layout_check_lines: assertion failed: (!layout->log_attrs) Aborted

关于我做错了什么的任何建议?我(显然)是线程新手。

4

2 回答 2

8

我不确定这是否是导致您出现问题的原因,但是...您不应该从另一个线程与 GUI 交互。你应该使用wx.CallAfter(). 我也会考虑在循环中添加睡眠。

wx.CallAfter()文档说:

在当前和待处理的事件处理程序完成后调用指定的函数。这对于从非 GUI 线程进行 GUI 方法调用也很有用。任何额外的位置或关键字参数都会在调用时传递给可调用对象。

更新后的代码将是:

import wx
import thread
import time

class Example(wx.Frame):
    def __init__(self, parent): 
        wx.Frame.__init__(self,parent)
        self.InitUI()

    def InitUI(self):
        self.SetSize((250, 200))
        self.Show(True)

        self.text = wx.StaticText(self, label='',pos=(20,30))

        thread.start_new_thread(self.watch,(self,None))

    def watch(self,dummy,e):
        while True:
            time.sleep(0.1)
            wx.CallAfter(self.text.SetLabel, 'Closed')

def main():
    ex = wx.App()
    Example(None)
    ex.MainLoop()    

if __name__ == '__main__':
    main() 

也许您也可以考虑使用wx.Timer

顺便说一句:您的代码在我的装有 Windows 7 和 wxPython 2.8 的 PC 上运行良好。

于 2013-01-14T15:27:48.993 回答
1

除了后台线程不更新规则之外,我发现在类似情况下(UI 对象的高频更新),仅在值与已显示的值发生变化时才更新值确实有帮助。这可以大大减少应用程序的负载,因为如果值没有改变,那么就不需要发送和处理绘制事件、将像素移动到屏幕等。所以在这个例子中,我将添加一个名为的新方法通过 CallAfter 将小部件中的当前值与请求的值进行比较,并且仅在它们不同时才调用 SetLabel。

于 2013-01-16T19:05:40.923 回答