运行一分钟后出现 Pango 错误
我有以下 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()
settimer.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
I have the following python modules. Sorry if the code is ugly. This is my first python GUI app and I'm fairly new to python as well. It's some sort of a count down timer with a todo list. It works kinda well except that after two minutes after running the program, it crashes with the following error:
Pango:ERROR:/build/buildd/pango1.0-1.28.0/pango/pango-layout.c:3739:pango_layout_check_lines: assertion failed: (!layout->log_attrs)
I have absolutely no idea what that even means. One I'm confused about is that it works after the first minute, ie. the timer label counts down ok but on the next minute, it crashes immediately.
After googling a bit, I think the issue might be related to multithreading? Any ideas?
#!/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()
timer.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()
settimer.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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该使用
wx.Timer
而不是启动大部分时间都在等待的线程。wx.Timer
将在指定的时间间隔内调用您的代码。You should have used
wx.Timer
instead of starting a thread that will be most of the time waiting.wx.Timer
will call your code in the specified interval.