PyQt5中QThread:Worker类构造函数中创建新对象是否可行?
Great question—let’s unpack this clearly, since thread affinity in Qt (and PyQt5) is a common point of confusion.
First, let’s recap the C++ rule you referenced from Maya Posch:
QObject构造函数中分配堆对象会使对象归主线程所有,应在槽函数中分配。
The Short Answer
Yes, this rule applies fully to PyQt5—but with a small caveat for non-QObject Python objects. Here’s why:
The Core Reason: Thread Affinity in Qt
Every QObject (and its subclasses) has a "thread affinity"—the thread it belongs to. By default, this is set to the thread that executes the object’s constructor.
In typical PyQt5 worker-object setups:
- You create the
Workerinstance in the main thread - You call
worker.moveToThread(your_qthread)to assign the worker to a child thread
If you create a QObject subclass (like QNetworkAccessManager, QTimer, or another custom QObject) inside the Worker’s __init__ method, that object will inherit the main thread’s affinity—even after you move the Worker to the child thread. This is because the constructor ran in the main thread before the worker was moved.
Why This Matters
If you try to interact with that main-thread-affine object from the Worker’s slots (which run in the child thread), you’ll be making cross-thread calls to a QObject. Qt enforces thread safety for QObjects, so this can lead to:
- Silent failures
- Runtime warnings about unsafe cross-thread operations
- Crashes in worst-case scenarios
The Correct Approach (Same as C++)
Just like in C++, you should create any QObject subclass objects inside the Worker’s slot functions (the ones that run in the child thread). Since slots execute in the Worker’s assigned thread, any QObjects created there will have the child thread’s affinity, keeping all operations thread-safe.
Example: Bad vs. Good Implementation
❌ Bad (QObject created in constructor)
from PyQt5.QtCore import QObject, pyqtSlot from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QUrl class Worker(QObject): def __init__(self): super().__init__() # This manager is created in the main thread—affinity stays main thread self.network_manager = QNetworkAccessManager() @pyqtSlot() def perform_work(self): # Risky: calling a main-thread QObject from child thread self.network_manager.get(QNetworkRequest(QUrl("https://example.com")))
✅ Good (QObject created in slot)
from PyQt5.QtCore import QObject, pyqtSlot from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QUrl class Worker(QObject): def __init__(self): super().__init__() self.network_manager = None @pyqtSlot() def perform_work(self): # Slot runs in child thread—manager gets child thread affinity self.network_manager = QNetworkAccessManager() self.network_manager.get(QNetworkRequest(QUrl("https://example.com")))
The Caveat: Non-QObject Python Objects
If you’re creating plain Python objects (not subclasses of QObject), they don’t have thread affinity at all. You can safely create these in the Worker’s constructor—they’ll work fine in the child thread since they don’t rely on Qt’s thread mechanism.
内容的提问来源于stack exchange,提问作者K.Mulier

