使用wx.Timer总是发送wx.EVT_PAINT消息而不是wx.EVT_TIMER

0 投票
1 回答
858 浏览
提问于 2025-04-16 09:41

我有一个wx.Dialog(对话框),我对它进行了子类化。在这个对话框里,我自己在DC(设备上下文)上绘图,同时我还有一个wx.Timer(定时器),它每100个时钟步循环一次。

现在发生的情况是,当我通过self.timer.Start(100)来启动我的wx.Timer时,它确实每100个时钟步循环一次,但它每100个时钟步发送给对话框的是wx.EVT_PAINT消息,而不是wx.EVT_TIMER消息?

从我下面的例子很容易看出,如果你运行它,你会发现字符串“Got Paint”总是被打印出来,而“Got Timer”从来没有被打印(wx.EVT_TIMER事件从未被接收到?)

这是为什么呢?我该怎么解决这个问题呢?

import wx

class dlg( wx.Dialog ):

    def __init__( self, _parent ):

        wx.Dialog.__init__( self, parent=_parent, id=wx.ID_ANY )

        self.Show()

        self.w = wx.Timer( self )
        self.Bind( wx.EVT_TIMER, self.on_timer, self.w )
        self.Bind( wx.EVT_PAINT, self.on_paint )
        self.w.Start(100)


    def on_timer( self, event ):

        print "Got Timer"
        raw_input()

    def on_paint( self, event ):

        print "Got Paint"
        raw_input()



class Frame( wx.Frame ):

    def __init__( self, _parent ):

        wx.Frame.__init__( self, parent=_parent, id=wx.ID_ANY )

        self.Bind( wx.EVT_CLOSE, self.on_close )

        self.w = dlg( self )


    def on_close( self, event ):

        self.Close( True )
        self.Destroy()



if __name__ == "__main__":

    app   = wx.App(False)
    frame = Frame( None )

    frame.Show()
    app.MainLoop()

1 个回答

1

如果你在使用Windows系统,那么问题在于你没有在EVT_PAINT处理函数中创建一个wx.PaintDC。当Windows处理完这个事件后,它发现窗口还有一些需要更新的地方,所以它会立刻发送另一个绘制事件,这个事件的优先级更高。这就导致其他事件被“饿死”,所以在你的例子中看起来就像没有定时器事件被发送一样。

如果你不是在使用Windows,请提供更多的细节。

撰写回答