2010-10-20 73 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線程中手動運行垃圾回收 。

他在那裏發佈了一個代碼示例。