如何调试Python GUI程序?

1 投票
1 回答
544 浏览
提问于 2025-04-16 21:35

我想调试一个用Python写的程序,比如calibre。通常,我会使用pdb在控制台里调试,但当我用pdb调试带有图形界面的程序时,界面部分(比如画布之类的)会卡住,这样调试起来就非常困难。

有没有什么建议可以帮助调试Python的图形界面程序?你们是怎么做的呢?

1 个回答

0

我会在我的图形用户界面(GUI)代码中,每个处理用户操作的函数或方法的开头加上logging.debug的调用,比如鼠标点击或者按下回车键。同时,任何更新视图的高级函数也会在开头加上logging.debug。这些日志信息会记录函数或方法中使用的重要信息。因为这些信息是以DEBUG级别记录的,所以你可以通过简单的配置来开启或关闭它们。

另外,虽然这种方法不太高级,但如果你想快速找到问题,可以暂时不使用logging模块,而是直接用print语句来输出信息。

下面是我写的一段代码,用来初始化logging模块,并设置一个循环日志文件:

import pytz

timestamp_detailed_format = '%Y-%m-%d %H:%M:%S.%f %Z'

def detailed_format(date):
  u"Given a datetime object return a detailed representation including fractional seconds and time zone"
  return unicode(date.strftime(timestamp_detailed_format))

def localize_epoch_time(epoch_time, timezone=pytz.UTC):
  u"Given an epoch time return an accurate, timezone-aware datetime object"
  t = localtime(epoch_time)
  epochdt = datetime(*(t[:6] + (int((epoch_time - long(epoch_time)) * 1000000),))).astimezone(timezone)
  if hasattr(timezone, 'normalize'):  # pytz tzinfo objects have this
    return timezone.normalize(epochdt)
  else: # tzinfo object not from pytz module
    return epochdt

class TimezoneAwareFormatter(logging.Formatter):
  u"custom log formatter using timezone-aware timestamps"
  def __init__(self, logformat=None, timezone=pytz.UTC):
    logging.Formatter.__init__(self, logformat)
    self._timezone = timezone
  def formatTime(self, record, _=None):
    u"times will be formatted as YYYY-MM-DD HH:MM:SS.ssssss TZ"
    return detailed_format(localize_epoch_time(record.created, self._timezone))

def simple_log_file(filename, logname=None, level=logging.NOTSET,
                    threshold=10485760, generations=2, quiet=False, timezone=pytz.UTC):
  u"initialize logging API for a simple generational log file, return logger object"
  formatter = TimezoneAwareFormatter('%(asctime)s %(levelname)s %(message)s', timezone)
  handler = logging.handlers.RotatingFileHandler(filename, 'a', threshold, generations, 'UTF-8')
  handler.setFormatter(formatter)
  logger = logging.getLogger(logname)
  logger.addHandler(handler)
  logger.setLevel(level)
  if not quiet: logger.info(u'Logging to this destination has started')
  return logger

撰写回答