如何检查一个小部件是否在布局中?我有一个可能包含该小部件的布局。
- 小部件名称:
infoClient
- 图层名称:
verticalLayout_3
需要检查小部件是否存在于布局中,如果存在则不添加新的小部件。如果不存在,则添加一个新的小部件。如何实现呢?
void MainWindow::slotPush1()
{
if <there is no infoClient> ui->verticalLayout_3->addWidget(new infoClient(this));
}
如何检查一个小部件是否在布局中?我有一个可能包含该小部件的布局。
infoClient
verticalLayout_3
需要检查小部件是否存在于布局中,如果存在则不添加新的小部件。如果不存在,则添加一个新的小部件。如何实现呢?
void MainWindow::slotPush1()
{
if <there is no infoClient> ui->verticalLayout_3->addWidget(new infoClient(this));
}
几点说明:
layout()
不为空)或者小部件(widget()
不为空)。最终你会得到一个布局项树。因此,您需要从父小部件开始搜索(深度优先搜索,广度优先搜索)。
bool checkWidgetInsideLayout(const QWidget* _someWidget){
return _someWidget != NULL &&
_someWidget->parent() != NULL &&
_someWidget->parent()->layout() != NULL &&
foundItem(_someWidget->parent()->layout(), _someWidget );
}
//clumsy dfs
bool foundItem(const QLayout* layout, const QWidget* _someWidget ){
for(int i = 0; i < layout->count(); i++){
QLayoutItem* item = layout->itemAt(i);
if(item->widget() == _someWidget )
return true;
if(item->layout() && foundItem(item->layout(), _someWidget) )
return true;
}
return false;
}
Qt框架内部没有提供您所需的检查机制。您需要自行实现:
void MainWindow::slotPush1()
{
if (doesLayoutContainInfoClient(ui->verticalLayout_3))
{
ui->verticalLayout_3->addWidget(new infoClient(this));
}
}
bool MainWindow::doesLayoutContainInfoClient(QLayout* layout)
{
const QString infoClientName("infoClient");
for (int i=0; i<layout->count(); i++)
{
QWidget* layoutWidget = layout->itemAt(i)->widget();
if (layoutWidget)
{
if (infoClientName == layoutWidget->metaObject()->className())
{
return true;
}
}
}
return false;
}
尽管我上面提到了这种方法,但我并不真正推荐它。更明智的做法是在程序中将是否已将infoClient添加到布局中作为独立的布尔值进行存储。以这种方式查询布局的内容有点不寻常,并且比使用bool
更混乱。
使用QObject::findChild通过名称查找子项。例如:
void MainWindow::slotPush1()
{
if (ui->verticalLayout_3->findChild<QWidget*>("infoClient")) // your code to add it here
}
注意:findChild是一个模板函数。如果您不熟悉模板函数,只需要知道您要查找的对象类型(在您的示例中,看起来您可以使用 ui->verticalLayout_3->findChild<infoClient*>("infoClient")
)。如果您想查找QWidget或任何从QWidget继承的内容,只需使用 findChild<QWidget*>()
,这样就可以安全地实现。
if (!(ui->centralWidget->findChild<QWidget*>("infoClient"))) ui->verticalLayout_3->addWidget(new infoClient(this));
- SerJSQObject::findChild()
方法来查找您的子项。
但是,将Widget添加到QLayout中会将其重新分配给布局的父级。因此,您需要通过使用MainWindow
对象调用它来查找它:void MainWindow::slotPush1()
{
if (this->findChild<QWidget*>("infoClient")) {
// ...
}
}
void MainWindow::createWidgets()
{
if (infoClientShouldBeAdded) {
m_client = new infoClient(this);
m_client->setObjectName("infoClient");
ui->verticalLayout_3->addWidget(m_infoClient);
}
}
搜索此布局中的小部件widget(不包括子布局)。 返回widget的索引,如果未找到widget,则返回-1。