2016-12-14 65 views
0

現在我想創建一個線程,並把我的類「AVC_file」inatance。Qt線程ID等於MainWindows? (moveToThread)

但是,當我在textBroswer中打印currentThreadId時,發現MainWindows的threadID與我創建的線程相同。像下面顯示的pitures。

Framework::Framework(QWidget * parent) : QMainWindow(parent) 
{ 
    ui.setupUi(this); 

    int threadID = (int)QThread::currentThreadId(); 
    ui.textBrowser->append("Main Tread ID : " + QString::number(threadID)); 
} 

void Framework::on_OpenAVCFile_clicked() 
{ 
    QString filePath = QFileDialog::getOpenFileName(
     this, tr("Open File"), "C:\\", "AVC File (*.avc)" 
    ); 


    if (!filePath.isEmpty()) 
    { 
     QMessageBox::information(this, tr("File Name"), filePath); 
    } 

    QFile file(filePath); 
    if (!file.open(QIODevice::ReadOnly)) 
    { 
     QMessageBox::information(0, "info", file.errorString()); 
    } 
    else { 
     QThread *thread = new QThread(this); 
     int threadID = (int)thread->currentThreadId(); 
     ui.textBrowser->append("Second Tread ID : " + QString::number(threadID) + "\n"); 
     AVC_File *AVC_file = new AVC_File(); 

     AVC_file->moveToThread(thread); 
     connect(AVC_file, SIGNAL(requestFileContent(QString)), this, SLOT(addFileContent(QString))); 
     connect(AVC_file, SIGNAL(requestFileDebug(QString)), this, SLOT(addFileDebug(QString))); 
     connect(AVC_file, SIGNAL(requestFileCorrectness(bool, int)), this, SLOT(adddFileCorrectness(bool, int))); 
     connect(AVC_file, SIGNAL(requestNewValue(unsigned int, int)), this, SLOT(addNewValue(unsigned int, int))); 
     thread->start(); 

     AVC_file->AVC_FileCheck(file); 
    } 
} 

圖片關於我的代碼和結果 - > Main Windows, create thread and results

哦,我還試着用我的 「AVC_file」 實例發出信息如下圖所示!?。

void AVC_File::AVC_FileCheck(QFile &file) 
{ 
    int threadID = (int)QThread::currentThreadId(); 
    emit requestFileContent("Thread ID by emit" + QString::number(threadID) + "\n"); 
    QTextStream in(&file); 
    ........ 
    ........ 
} 

Emit threadID info

任何人都可以幫我嗎?

順便說一句,我使用Visual Studio Qt插件開發此項目。

回答

2

我會按隨機順序解決幾個問題。

首先,使用線程ID是不好的用戶體驗。給螺紋一個描述性的名稱:

int main(...) { 
    QApplication app(...); 
    QThread myThread; 
    MyObject myObject; 
    myObject->moveToThread(&myThread); 
    QThread::currentThread()->setObjectName("mainThread"); 
    myThread.setObjectName("myThread"); 
    ... 
} 

然後使用QThread::currentThread()->objectName()進行檢索。您也可以通過QObject*qDebug()顯示線程的名稱:

qDebug() << QThread::currentThread(); 

你的信號調用將隨即成爲:

QString currentThreadName() { 
    return QThread::currentThread()->objectName().isEmpty() ? 
    QStringLiteral("0x%1").arg(QThread::currentThread(), 0, 16) : 
    QThread::currentThread()->objectName(); 
} 

    ... 
    emit requestFileContent(
    QStringLiteral("Emitting from thread \"%1\"\n").arg(currentThreadName)); 

然後,使用上述處理你所創建的線程:

auto thread = new QThread(this); 
    thread->setObjectName("fileThread"); 
    ui.textBrowser->append(QStringLiteral("Worker thread: \"%1\").arg(thread->objectName())); 
    auto AVC_file = new AVC_File; 

    AVC_file->moveToThread(thread); 
    ... 

但是從主線程調用AVC_FileCheck。無論是否正確取決於該方法的實施方式。它需要是線程安全的,請參閱this question對此進行討論。 TL; DR:下面的模式可能是一個起點:

class AVC_file : public QObject { 
    Q_OBJECT 
    Q_SLOT void fileCheck_impl(QIODevice * dev) { 
    dev->setParent(this); 
    ... 
    } 
    Q_SIGNAL void fileCheck_signal(QIODevice *); 
public: 
    void fileCheck(QIODevice *dev) { fileCheck_signal(dev); } 
    AVC_file(QObject *parent = nullptr) : QObject(parent) { 
    connect(this, &AVC_file::fileCheck_signal, this, &AVC_file::fileCheck_impl); 
    ... 
    } 
}; 

最後,現有的AVC_fileCheck API是壞了。您通過QFile作爲參考:這不會起作用,因爲只要on_OpenAVCFile_clicked返回,它就不復存在。當AVC_file在其線程中使用該文件時,它是一個懸掛的對象引用。

相反,您必須將文件的所有權傳遞給AVC_file,並將指針傳遞給AVC_file將在處理完成時處置的實例。或者乾脆讓AVC_file爲你打開文件!

5

QThread::currentThreadId()是一種靜態方法。

當你調用它時,它會返回執行它的線程的線程ID。

在你的情況下,這是主線程。

+0

根據你的回答,我如何在主線程中獲得另一個線程ID? – WilliamChen

+0

爲什麼你需要一個新的ID?也許在你的AVC_File中存儲一個ID用於識別。 –