2017-08-14 77 views
1

Qt具有與小部件分開的佈局系統類型,這會導致我出現問題。我知道,當我有一個了QSplitter,我可以做Qt小部件在彼此之上堆疊子佈局

new SomeCustomQWidget(splitter); 

但是添加的東西給它,如果我有一個QWidget,我不應該能夠做同樣的事情? Qt網頁僅解釋如何將layoutItems添加到佈局,只通過繼承兩個子類來將它們連接到小部件。所以,正確的無我做這樣的事情

item = new QWidget(parentsplitter); //this works 
subitem = new customWidget(item); //this too 
subitem2 = new QSlider(item); //this isn't laid out with subitem 

然而,這導致滑動器的子項的頂部,而不是被旁邊(右側或低於我期望)。調用

//either 
new QVBoxLayout(item); 
//or 
item->setLayout(new QVBoxLayout()); 
//or 
item->setLayout(new QVBoxLayout(item)); 

在初始化項目後沒有幫助。 (我的邏輯是該項目將佈局作爲子項目並將添加後續子項)。

我早些時候解決了這個問題,但現在我在QGraphicsView中製作一個小部件時面臨完全相同的問題。我覺得應該不需要爲我想要動態添加到這些小部件的每個項目創建一個自定義子類,就像Qt網站所期望的那樣。 (如果我只是想添加一些文本和幾個按鈕,我真的需要製作2個自定義子類嗎?)我使用.ui文件進行基本佈局,但這些項目需要動態創建。

解決方案

忘了打電話給item->show();在用於佈局的部件。

原來,我測試過其他正確的代碼,但由於我的一些子類調用了show(),但其他一些子類卻沒有,所以這只是對我而言是打破了。

但這不是graphicswidgets的問題,因爲graphicslayout只能用於添加graphicslayoutite,它不包括例如graphicstextitems。

解決方案2 使用QGraphicsProxyWidget代替QGraphicsWidget固定的問題!

回答

1
QWidget *parent = new QWidget(); 
QVBoxLayout *rootLayout = new QVBoxLayout(parent); 
QHBoxLayout *subLayout1 = new QHBoxLayout(); 
QHBoxLayout *subLayout2 = new QHBoxLayout(); 
rootLayout->addLayout(subLayout1); 
rootLayout->addLayout(subLayout2); 

subLayout1->addWidget(new QLabel("Foo")); 
subLayout1->addWidget(new QLabel("Bar")); 

subLayout2->addWidget(new QPushButton("Foo button")); 
subLayout2->addWidget(new QPushButton("Bar button")); 

parent->show(); 

注意一旦佈局由setLayout的指派給小部件或當widger被傳遞到構造FO佈局,在1對1的關係,其持續到插件或佈局被破壞。請參閱documentation

如果已經在此窗口小部件上安裝了佈局管理器,則QWidget不會讓您安裝另一個窗口。您必須先刪除現有佈局管理器(由layout()返回),然後才能使用新佈局調用setLayout()。

這就是爲什麼subitem2 = new QSlider(item)不適合你。

0

我覺得你很困惑父母/孩子的關係與管理佈局。

讓我們從佈局開始。在小部件上設置時,佈局將成爲該小部件的子項。當使用窗口小部件父窗體構建時,窗口小部件將變爲父窗體,並在窗口小部件上設置佈局。在向佈局添加小部件時,它們將成爲佈局設置的小部件的子項,而不是佈局本身。在小部件上設置父項或用父項構建小部件不會自動將小部件添加到其父佈局。刪除佈局不會刪除由它控制的小部件,因爲它們不是它的子項。

總結 - 佈局和養育是兩個不同的機制。首先是管理小部件的位置和大小,另一個是用於對象層次和資源管理(父母刪除他們的子女)。雖然佈局有一個方便的構造函數,但這兩者都是 - 設置佈局的父級,並在父級小部件上設置佈局。

在代碼:

item = new QWidget() 
layout = new QVBoxLayout(item); 

等同於:

item = new QWidget(); 
layout = new QVBoxLayout(); 

layout->setParent(item); 
item->setLayout(layout); 

該代碼添加一個孩子的佈局和項目成爲其母公司:

item = new QWidget(); 
layout = new QVBoxLayout(item); 
child = new QWidget(); 
layout->addWidget(child); 

這增加了孩​​子到父項,但是不是添加孩子到佈局:

item = new QWidget(); 
layout = new QVBoxLayout(item); 
child = new QWidget(item); 

一個了QSplitter的特殊之處在於它是一個小部件,當你使用分離器作爲窗口小部件的幾何形狀由分離器支配的小工具的父它自己的孩子,即佈局。其他小部件的行爲不像那樣。

所以要註釋代碼:

item = new QWidget(parentsplitter); //this works because splitter does layout 
subitem = new customWidget(item); //item is not splitter so subitem geometry is not managed 
subitem2 = new QSlider(item); //item is not splitter so subitem2 geometry is not managed 

如果你想展示的項目子項目,然後按項目要麼必須是一個分離器也還是有一個佈局將管理孩子,所以:

childsplitter = new QWidget(parentsplitter); //note that parentsplitter has only 1 item 
subitem = new customWidget(childsplitter); 
subitem2 = new customWidget(childsplitter); 

widget = new QWidget(parentsplitter); //note that parentsplitter has only 1 item 
lay = new QHBoxLayout(widget); 
subItem = new customWidget(); 
subItem2 = new customWidget(); 
lay->addWidget(subItem); 
lay->addWidget(subItem2); 

如果你想父母分離器有兩個項目,那麼你做的事:

item = new customWidget(parentsplitter); 
item2 = new customWidget(parentsplitter);