據我所知,沒有什麼Qt文檔在說,這是一種不好的做法。
我做了很多次,特別是在我對象被告知的東西從一個線程發生的情況下(監聽COM端口,或藍牙連接),需要一個GUI更新:
MyObject::MyObject()
{
connect(this, SIGNAL(dataReceived(QString)), this, SLOT(showData(QString)), Qt::ConnectionType::QueuedConnection);
}
void MyObject::receiveSomeData(QString data)
{
// a worked thread called this function...
// we are not in the main thread here, it's unsafe to update the GUI,
// calling showData(data) will lead most likely lead to crashs or Qt warnings
// so let's delay it's execution by emitting dataReceived!
emit dataReceived(data);
}
void MyObject::showData(QString data)
{
// now it's safe to update the GUI...we are back to main thread
m_ui.label->setText(data);
}
也沒這種技巧在基於Qt的類構造函數中需要等待小部件實際可見,然後才能執行一些GUI操作(例如需要訪問小部件的大小......在構造函數中,佈局尚未被視爲約束大小的小部件)。然後,我不得不emit
從窗口小部件構造函數signal
,該信號被連接到同一個控件類,會做初始化的slot
和Qt::ConnectionType::QueuedConnection
使得之後的Widget,實際去看到的初始化函數來執行。
而且可能還有其他的情況下,這是有關...
注:由於ymoreau評論的OP,這也可以通過使用QMetaObject::invokeMethod
其中最有可能最後也做了同樣的事情不客氣。
在我看來,這不是一個反模式,但我不能看到這一點,不能進行對設計水平簡單的任何使用情況。爲什麼你想排隊你的電話執行?一個簡單的循環不適合你的需求?如果沒有,你可以用做完全一樣的例子沒有信號'[靜態]布爾QMetaObject :: invokeMethod' – ymoreau
試想具有信號('MyFoo :: ready')和插槽('MyFoo的選項: :ready')分開的課程。如果他們可以屬於不同的班級,那麼最終可能會有更好的設計。如果你的目標只是排隊插槽呼叫,你可能想看看這個[答案](https://stackoverflow.com/a/41910566/2666212)。 – Mike