1

我有以下 python 模块。对不起,如果代码很难看。这是我的第一个 python GUI 应用程序,我对 python 也很陌生。这是某种带有待办事项列表的倒计时计时器。它工作得很好,只是在运行程序两分钟后,它崩溃并出现以下错误:

Pango:ERROR:/build/buildd/pango1.0-1.28.0/pango/pango-layout.c:3739:pango_layout_check_lines: assertion failed: (!layout->log_attrs)

我完全不知道这甚至意味着什么。我感到困惑的是它在第一分钟后起作用,即。计时器标签倒计时正常,但在下一分钟,它立即崩溃。

谷歌搜索了一下,我认为这个问题可能与多线程有关?有任何想法吗?

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.3 on Fri Jul  9 17:00:08 2010

import wx
import settimer

# begin wxGlade: extracode
# end wxGlade

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.todo1 = wx.TextCtrl(self, -1, "")
        self.timer_label1 = wx.StaticText(self, -1, "00:00")
        self.set_timer1 = wx.Button(self, -1, "Set Timer")
        self.todo2 = wx.TextCtrl(self, -1, "")
        self.timer_label2 = wx.StaticText(self, -1, "00:00")
        self.set_timer2 = wx.Button(self, -1, "Set Timer")
        self.todo3 = wx.TextCtrl(self, -1, "")
        self.timer_label3 = wx.StaticText(self, -1, "00:00")
        self.set_timer3 = wx.Button(self, -1, "Set Timer")
        self.todo4 = wx.TextCtrl(self, -1, "")
        self.timer_label4 = wx.StaticText(self, -1, "00:00")
        self.set_timer4 = wx.Button(self, -1, "Set Timer")
        self.todo5 = wx.TextCtrl(self, -1, "")
        self.timer_label5 = wx.StaticText(self, -1, "00:00")
        self.set_timer5 = wx.Button(self, -1, "Set Timer")
        self.hours = 0
        self.minutes = 0

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.on_set1, self.set_timer1)
        self.Bind(wx.EVT_BUTTON, self.on_set2, self.set_timer2)
        self.Bind(wx.EVT_BUTTON, self.on_set3, self.set_timer3)
        self.Bind(wx.EVT_BUTTON, self.on_set4, self.set_timer4)
        self.Bind(wx.EVT_BUTTON, self.on_set5, self.set_timer5)
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("Track Work")
        self.todo1.SetMinSize((300, 25))
        self.timer_label1.SetMinSize((100, 30))
        self.timer_label1.SetFont(wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.set_timer1.SetMinSize((85, 27))
        self.todo2.SetMinSize((300, 25))
        self.timer_label2.SetMinSize((100, 30))
        self.timer_label2.SetFont(wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.set_timer2.SetMinSize((85, 27))
        self.todo3.SetMinSize((300, 25))
        self.timer_label3.SetMinSize((100, 30))
        self.timer_label3.SetFont(wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.set_timer3.SetMinSize((85, 27))
        self.todo4.SetMinSize((300, 25))
        self.timer_label4.SetMinSize((100, 30))
        self.timer_label4.SetFont(wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.set_timer4.SetMinSize((85, 27))
        self.todo5.SetMinSize((300, 25))
        self.timer_label5.SetMinSize((100, 30))
        self.timer_label5.SetFont(wx.Font(15, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.set_timer5.SetMinSize((85, 27))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        flex_sizer = wx.FlexGridSizer(5, 3, 2, 25)
        flex_sizer.Add(self.todo1, 0, 0, 0)
        flex_sizer.Add(self.timer_label1, 0, 0, 0)
        flex_sizer.Add(self.set_timer1, 0, 0, 0)
        flex_sizer.Add(self.todo2, 0, 0, 0)
        flex_sizer.Add(self.timer_label2, 0, 0, 0)
        flex_sizer.Add(self.set_timer2, 0, 0, 0)
        flex_sizer.Add(self.todo3, 0, 0, 0)
        flex_sizer.Add(self.timer_label3, 0, 0, 0)
        flex_sizer.Add(self.set_timer3, 0, 0, 0)
        flex_sizer.Add(self.todo4, 0, 0, 0)
        flex_sizer.Add(self.timer_label4, 0, 0, 0)
        flex_sizer.Add(self.set_timer4, 0, 0, 0)
        flex_sizer.Add(self.todo5, 0, 0, 0)
        flex_sizer.Add(self.timer_label5, 0, 0, 0)
        flex_sizer.Add(self.set_timer5, 0, 0, 0)
        self.SetSizer(flex_sizer)
        flex_sizer.Fit(self)
        self.Layout()
        # end wxGlade
    def on_set1(self, event): # wxGlade: MyFrame.<event_handler>
        app = wx.PySimpleApp(0)
        wx.InitAllImageHandlers()
        MyTimer = settimer.Timer(None, -1, "")
        MyTimer.get_out_instance(self)
        app.SetTopWindow(MyTimer)
        MyTimer.Show()
        app.MainLoop()
        event.Skip()

    def set_label(self):
        self.timer_label1.SetLabel("%02d:%02d" % (self.hours, self.minutes))
        self.minutes -= 1

# end of class MyFrame

if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    main_frame = MyFrame(None, -1, "")
    app.SetTopWindow(main_frame)
    main_frame.Show()
    app.MainLoop()

计时器.py

import threading
import time

class Timer(threading.Thread):
    def __init__(self, seconds, track):
        threading.Thread.__init__(self)
        self.total_time = seconds
        self.track = track

    def run(self):
        for sec in range(self.total_time):
            time.sleep(60)
            self.track.set_label()

设置定时器.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.3 on Fri Jul  9 16:49:11 2010

import wx
import timer

# begin wxGlade: extracode
# end wxGlade



class Timer(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: Timer.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.hours_text = wx.TextCtrl(self, -1, "")
        self.hours = wx.StaticText(self, -1, "HH")
        self.minutes_text = wx.TextCtrl(self, -1, "")
        self.minutes = wx.StaticText(self, -1, "MM")
        self.set = wx.Button(self, -1, "Set")
        self.out_instance = None
        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.on_set, self.set)
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: Timer.__set_properties
        self.SetTitle("Set Timer")
        self.hours_text.SetMinSize((40, 25))
        self.hours.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.minutes_text.SetMinSize((40, 25))
        self.minutes.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.set.SetMinSize((50, 27))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: Timer.__do_layout
        flex_sizer = wx.FlexGridSizer(1, 5, 0, 4)
        flex_sizer.Add(self.hours_text, 0, 0, 0)
        flex_sizer.Add(self.hours, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        flex_sizer.Add(self.minutes_text, 0, 0, 0)
        flex_sizer.Add(self.minutes, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        flex_sizer.Add(self.set, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        self.SetSizer(flex_sizer)
        flex_sizer.Fit(self)
        flex_sizer.AddGrowableRow(1)
        flex_sizer.AddGrowableCol(3)
        self.Layout()
        # end wxGlade

    def get_out_instance(self, out):
        # get the instance of trackwork 
        # this method is meant to be called outside this class
        self.out_instance = out

    def on_set(self, event): # wxGlade: Timer.<event_handler>
        self.out_instance.hours = int(self.hours_text.GetValue())
        self.out_instance.minutes = int(self.minutes_text.GetValue())
        self.out_instance.set_label()
        t = timer.Timer(self.out_instance.minutes, self.out_instance)
        t.start()
        self.Destroy()
        event.Skip()

# end of class Timer
4

1 回答 1

0

您应该使用wx.Timer而不是启动一个大部分时间都在等待的线程。

wx.Timer将在指定的时间间隔内调用您的代码。

于 2010-07-12T00:45:16.763 回答