2010-10-20 74 views
4

我正在使用Qt 4.7和PyQt 4.7来构建一个多线程的GUI程序。我一直在认真地管理PyQt对象,以便它们保持在一个UI线程中以避免同步问题,并且一般都没有问题。如何防止从不同线程垃圾收集PyQt对象?

但是有时候,python垃圾收集器从其他线程被激活的时候,Qt对象的析构函数被调用到那里,下面的断言在Qt中失败。

即使对于调试版本,我也可以定义QT_NO_DEBUG,它应该没问题,因为收集的对象几乎不会导致同步问题。但是,我认为关闭其他调试消息并不是一个好主意。我如何防止这种情况发生?

 
#if !defined (QT_NO_DEBUG) || defined (QT_MAC_FRAMEWORK_BUILD) 
void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver) 
{ 
    QThread *currentThread = QThread::currentThread(); 
    QThread *thr = receiver->thread(); 
    Q_ASSERT_X(currentThread == thr || !thr, 
       "QCoreApplication::sendEvent", 
       QString::fromLatin1("Cannot send events to objects owned by a different thread. " 
            "Current thread %1. Receiver '%2' (of type '%3') was created in thread %4") 
       .arg(QString::number((quintptr) currentThread, 16)) 
       .arg(receiver->objectName()) 
       .arg(QLatin1String(receiver->metaObject()->className())) 
       .arg(QString::number((quintptr) thr, 16)) 
       .toLocal8Bit().data()); 
    Q_UNUSED(currentThread); 
    Q_UNUSED(thr); 
} 
#elif defined(Q_OS_SYMBIAN) && defined (QT_NO_DEBUG) 

回答

0

我会推荐使用pyqtSignal。当任务完成并且接收器变成信号的连接功能时,您可以创建线程发送的信号。

5

这个问题在线程弹出PyQt的邮件列表上

“微妙的bug PyQt的结合Python的垃圾收集器”
http://www.riverbankcomputing.com/pipermail/pyqt/2011-August/030376.html

Kovid戈亚尔在
http://www.riverbankcomputing.com/pipermail/pyqt/2011-August/030378.html提出了一个解决方法

他在哪里写道:

作为我项目中的解决方法, 我禁用了自动垃圾回收器,并通过QTimer在GUI线程中手动运行垃圾回收 。

他在那里发布了一个代码示例。