如何检查窗口小部件是否在布局中?我有一个可能包含小部件的布局。
infoClient
verticalLayout_3
需要检查布局中是否存在窗口小部件,然后不要添加新窗口小部件 如果不存在,请添加一个新的 怎么做?
void MainWindow::slotPush1()
{
if <there is no infoClient> ui->verticalLayout_3->addWidget(new infoClient(this));
}
答案 0 :(得分:3)
几点:
layout()
不为空)或窗口小部件(widget()
不为空)。最后,你有一个布局项目树。所以你需要从父窗口小部件(dfs,bfs)进行搜索。
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;
}
答案 1 :(得分:2)
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
更麻烦。
答案 2 :(得分:1)
使用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*>()
,这样你就会安全。
答案 3 :(得分:0)
我同意Tom Panning使用QObject::findChild()
方法找到您孩子的解决方案。
但是向QLayout添加一个Widget会将其重新显示给布局的父级。所以你必须通过这样的MainWindow
对象来调用它来找到它:
void MainWindow::slotPush1()
{
if (this->findChild<QWidget*>("infoClient")) {
// ...
}
}
如果您的infoClient小部件已添加到QtDesigner中,则此解决方案不会出现问题。设计者默认设置对象名称。 如果将infoClient添加到代码中的布局中,则必须显式设置对象名称,否则您将无法找到它,因为其名称为空: (假设,m_client是MainWindow的成员变量)
void MainWindow::createWidgets()
{
if (infoClientShouldBeAdded) {
m_client = new infoClient(this);
m_client->setObjectName("infoClient");
ui->verticalLayout_3->addWidget(m_infoClient);
}
}
答案 4 :(得分:0)
另一种可能性是跟踪创建的小部件的指针(例如,通过将它们存储在std :: vector或Qt等效项中)。这允许使用indexof(QWidget*):
在此布局中搜索窗口小部件窗口小部件(不包括子布局)。 返回小部件的索引,如果找不到小部件,则返回-1。