1

我编写了一个 PySide Windows 应用程序,它使用 libvlc 来显示视频、记录击键并将有关这些击键的聚合信息写入文件。我遇到了两个导致应用程序崩溃的错误(此处的其他问题-> https://stackoverflow.com/questions/18326943/pyside-qlistwidget-crash)。

应用程序每隔五分钟在视频上写入一次击键文件。用户可以更改播放速度,让五分钟的间隔可能需要多于或少于五分钟;它不受计时器控制。

写入文件时视频继续播放,因此我创建了一个继承自 threading.Thread 的对象用于文件创建 - IntervalFile。关于要写入的文件的一些信息在构造函数中传递;IntervalFile 根本不访问其父级(主 QWidget)。这是我在应用程序中使用的唯一线程对象。任何地方都没有声明计时器。

间歇性地,应用程序将崩溃,我将收到以下消息:“ QObject::killTimers: timers cannot be stop from another thread ”。

创建 IntervalFile 的代码是(CustomWidget 的一部分,继承自 QWidget):

def doIntervalChange(self):
  ...
  ifile = IntervalFile(5, filepath, dbpath) # db is sqlite, with new connection created within IntervalFile
  ifile.start()
  #end of def

使用信号从 QWidget 中调用 doIntervalChange。间隔文件是:

class IntervalFile(threading.Thread):
  def __init__(self, interval, filepath, dbpath):
    # declaration of variables

    threading.Thread.__init__(self)

  def run(self):
    shutil.copy('db.local', self.dbPath) # because db is still being used in main QWidget
    self.localDB = local(self.dbPath) # creates connection to sqlite db, with sql within the object to make db calls easier

    # query db for keystroke data
    # write file

    self.localDB.close()
    self.localDB = None

    os.remove(self.dbPath) # don't need this copy anymore

当 ifile.start() 被注释掉时,我没有看到 killTimers 崩溃。有什么建议么?请注意,崩溃似乎是随机的;有时我可以使用该应用程序(只是不断地反复按下相同的按键)一个小时而不会崩溃,有时它会在前几个间隔内。由于重现崩溃的困难,我认为这些代码行是问题所在,但我不是 100% 确定。

4

1 回答 1

0

I'm pretty sure you need to hold a reference to your thread object. When your doIntervalChange() method finishes, nothing is holding a reference to the thread object (ifile) any more and so it can be garbage collected. Presumably this is why the crash happens randomly (if the thread finishes it's task before the object is garbage collected, then you don't have a problem).

Not exactly sure what is creating the QTimers, but I'm fairly certain that won't affect my proposed solution!

So in doIntervalChange() save a reference to ifile in a list, and periodically clean up the list when threads have finished execution. Have a look at this for an idea (and if a better way to clean up threads shows up in that post, implement that!): Is there a more elegant way to clean up thread references in python? Do I even have to worry about them?

于 2013-10-19T11:41:18.723 回答