在 Qt 開發中,當主線程(GUI 線程)與子線程需要頻繁交互大量數據時,直接繼承 QThread 並重寫 run() 函數並不方便,因為 run() 無法接受參數,只能通過信號與槽機制傳遞數據。若僅涉及單向簡單交互尚可接受,但多次雙向交互時會顯得笨重。更靈活的方案是創建一個繼承自 QObject 的工作類,然後調用 moveToThread() 將其移至目標線程。
QObject,聲明所需的信號與槽,以及存儲數據的成員變量。QVector<QStringList>)必須先用 qRegisterMetaType 註冊。QThread 與工作對象,調用 moveToThread()。thread->start() 並發射啟動信號。// 工作類定義
class FileThread : public QObject {
Q_OBJECT
public:
QString m_path;
QFile *m_file;
signals:
void readend(QStringList headerList, QVector<QStringList> listArray, long row, long column);
public slots:
void getFile(QString path);
};
// 主線程中設置
FileThread *myFileThread = new FileThread();
QThread *thread = new QThread;
// 註冊跨線程傳遞的複雜類型
qRegisterMetaType<QStringList>("QStringList");
qRegisterMetaType<QVector<QStringList>>("QVector<QStringList>");
myFileThread->moveToThread(thread);
connect(this, SIGNAL(startRead(QString)), myFileThread, SLOT(getFile(QString)));
connect(myFileThread, SIGNAL(readend(QStringList, QVector<QStringList>, long, long)),
this, SLOT(showData(QStringList, QVector<QStringList>, long, long)));
thread->start();
emit startRead(filePath);
Q: 是否一定要用多線程?
A: 若任務簡單、耗時極短,單線程配合 QCoreApplication::processEvents() 即可;但涉及文件解析、網絡請求、複雜計算等長耗時操作,多線程是必須的。
Q: 如何控制線程數量?
A: 可維護一個 QThread 指針數組或 QVector<QThread*>,按需創建、啟動、等待銷毀,實現線程池式管理。