运行一分钟后出现 Pango 错误

发布于 2024-09-08 21:05:39 字数 7757 浏览 1 评论 0原文

我有以下 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

默嘫て 2024-09-15 21:05:39

您应该使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文