4

このプログラムでは、スレッドでwhileTrueループを使用するとエラーが発生します。ループがなければ、エラーは発生しません。もちろん、実際のプログラムでは、ラベルを継続的に更新することはありません。私が間違っていることについて何か考えはありますか?

これはプログラムです:

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の使用を検討することもできます。

ところで:あなたのコードは、Windows7とwxPython2.8を搭載したPCで問題なく実行されます。

于 2013-01-14T15:27:48.993 に答える
1

バックグラウンドスレッドからの更新なしのルールに加えて、同様の状況(UIオブジェクトの高頻度更新)では、値が既に表示されているものから変更された場合にのみ値を更新することが実際に役立つことがわかりました。値が変わらない場合は、ペイントイベントを送信して処理したり、画面にピクセルを移動したりする必要がないため、アプリケーションの負荷を大幅に減らすことができます。この例では、という新しいメソッドを追加します。 CallAfterを介して、ウィジェットの現在の値を要求された値と比較し、それらが異なる場合にのみSetLabelを呼び出します。

于 2013-01-16T19:05:40.923 に答える