如何防止PyQt对象从不同的线程收集垃圾?

Kyu*_*ark 4 python qt multithreading garbage-collection pyqt

我正在使用Qt 4.7和PyQt 4.7来构建一个多线程GUI程序.我一直在仔细管理PyQt对象,以便它们保留在一个UI线程中以避免同步问题,并且通常没有问题.

但有时候,在从其他线程激活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) 

小智 5

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

"PyQt中与Python垃圾收集器结合的微妙错误"
http://www.riverbankcomputing.com/pipermail/pyqt/20​​11-August/030376.html

Kovid Goyal在http://www.riverbankcomputing.com/pipermail/pyqt/20​​11-August/030378.html中提出了一种解决方法

他在哪里写道:

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

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


小智 1

我建议使用 pyqtSignal。您可以为线程创建信号,以便在任务完成时发送信号,并且接收器成为信号的连接函数。