Node Editor中有許多窗口获讳,它們都是 主窗口 QMainWindow
的子窗口惩坑。
Parameter Widget: 當點擊某個節(jié)點時,會顯示這個節(jié)點的信息占婉,以及可以調整的參數(shù)。 當前選中了 Comment 節(jié)點甫恩,在 Parameter Widget上可以顯示逆济、修改它的標題。同時 Comment節(jié)點也會聯(lián)動填物。
ListWidget: 節(jié)點列表纹腌。拖到 GraphicsView 時霎终,可以動態(tài)創(chuàng)建一個節(jié)點滞磺。
Graphics View: Graphics Scene 的視口。
image.png
這些窗口的父子關系如下莱褒,每一個方塊代表一個類击困。
窗口關系1.png
現(xiàn)在,需要判斷 Comment 節(jié)點是否被選中广凸。 如果選中阅茶,就根據(jù) Comment里的屬性字段,動態(tài)創(chuàng)建一個 QWidget
谅海,并添加到 Parameter Widget中脸哀。
Comment節(jié)點,其實是一個 QGraphicsItem
對象扭吁。判斷QGraphicsItem
是否被選中撞蜂,非常簡單盲镶,只要重寫一個虛函數(shù)即可:
QVariant DmGraphicsComment::itemChange(GraphicsItemChange change, const QVariant& value)
{
/* 如果 GraphicsItem “被選中”這個狀態(tài)發(fā)生了改變... */
if (change == QGraphicsItem::ItemSelectedChange)
{
if (!m_isSelected)
{
m_isSelected = true;
/* 做出相應的舉動 */
Self::OnSelected();
}
else
{
m_isSelected = false;
Self::OnUnselected();
}
}
return Super::itemChange(change, value);
}
如何根據(jù)屬性動態(tài)生成不同的QWidget
對象,需要反射的支持蝌诡,這個我們后來再說溉贿。我們假定下面代碼的dynamicUi
變量是已經生成好的,那么浦旱,現(xiàn)在的重點變?yōu)橛钌趺丛诋斍暗拇翱跇湎拢业?em>parameterWidget颁湖,然后把dynamicUi
掛在它的上面宣蠕,作為一個子窗口。
void DmGraphicsComment::OnSelected()
{
/* 要如何實現(xiàn)這個函數(shù)爷狈? */
QWidget* parameterWidget = FindWindowByObjectName("ParameterWidget");
assert(parameterWidget && "Parameter widget is nullptr");
/* 假定這個函數(shù)已經實現(xiàn) */
QWidget* dynamicUi = GenerateDynamicUi();
QLayout* layout = parameterWidget->layout();
layout->addWidget(dynamicUi );
}
方法非常簡單植影,只有三步:
- 給各窗口設置object name,比如MainWindow 的 object name 為
MainWindow
涎永, ParameterWidget 的 object name 為ParameterWidget
- 找到名叫MainWindow的頂層窗口
- 在 MainWindow的子窗口里尋找名叫
ParameterWidget
的子窗口
QWidget* DmGraphicsComment::FindWindowByObjectName(const QString& name)
{
/* 拿到 Graphics View 窗口 */
QGraphicsView* graphicsView = Super::scene()->views()[0];
assert(graphicsView && "Graphics view of the item is null");
/* 遍歷所有父窗口思币,直到找到名叫 MainWindow 的父窗口。 線性查找羡微。 */
QWidget* parentWidget = graphicsView->parentWidget();
assert(parentWidget && "Parent widget of the graphics view is null");
while (parentWidget && parentWidget->objectName() != "MainWindow")
{
parentWidget = parentWidget->parentWidget();
}
/* 調用 Qt Api谷饿,查找子窗口 */
QWidget* parameterWidget = parentWidget->findChild<QWidget*>(name);
/* 返回結果 */
return parameterWidget;
}