2015-05-06 86 views
2

我使用QPlainTextEdit來顯示一些文本。本文將在另一個線程比UI(主)線程修改(追加)與發送信號到微件訪問Qt窗口線程安全

connect(this, SIGNAL(addText(QString)), mUi->plainTextEditLog, SLOT(appendPlainText(QString))); 

... 
emit addText(QString::fromStdString(someString)); 
... 

另一個線程讀取該PlainTextEdit的文本,並將其寫入一個文件

QFile file(fileName); 
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { 
    return; 
} 
file.write(mUi->plainTextEditLog->toPlainText().toUtf8()); 
file.close(); 

就我所知,Qt小部件不是線程安全的。我想過一個互斥鎖來鎖定寫入信號發出,但這不會鎖定它,因爲它只是異步發送信號。

我使用信號的原因是寫入方法可以從多個線程中調用,互斥量在這種情況下無助於信號,但信號完美無缺。

第二個想法是將文本也存儲在我的課堂上,並通過互斥來鎖定字符串。但我不確定這是否非常有效,因爲不僅需要修改plaintextedit,而且還要將字符串作爲副本。

+0

爲你的第二種方法,當一切正常時擔心效率,**真**太慢。 –

+1

「我想過一個互斥鎖來鎖定寫入信號發出」<---沒必要。信號/插槽連接自動'線程安全'。 – Greenflow

+1

檢查你的Qt文檔並搜索:Qt :: QueuedConnection – Greenflow

回答

1

從本質上講,只要您將屬於另一個線程(請參閱QObject::moveToThread)的對象的信號連接到小部件(必須屬於主gui線程)時使用自動或排隊連接(請參見QObject::connect) ,那麼發出這個信號將是一個異步的「火警和忘記」呼叫。您也可以通過指定它是阻塞排隊連接來使呼叫同步,但除非您真的需要,否則我不會推薦它。

Qt中的線程模型花費了一些時間來解決你的問題,但是你會越來越喜歡多線程代碼中提供的簡單信號和插槽,以及多少代碼將不再需要用互斥鎖來保護它們的數據。