我正在使用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)
答案 0 :(得分:5)
此问题在线程
中的PyQt邮件列表中弹出“PyQt中与Python垃圾收集器结合的细微错误” http://www.riverbankcomputing.com/pipermail/pyqt/2011-August/030376.html
Kovid Goyal提出了一个解决方法 http://www.riverbankcomputing.com/pipermail/pyqt/2011-August/030378.html
他写道:
作为我项目的解决方法, 我禁用自动垃圾收集器并手动运行垃圾收集 在GUI线程中通过QTimer。
他在那里发布了一个代码示例。
答案 1 :(得分:0)
我建议使用pyqtSignal。您可以为线程创建信号,以便在任务完成且接收器成为信号连接功能时发送。