How to check whether a widget is in a layout? I have a layout that may contain the widget or not.
infoClient
verticalLayout_3
Need to check if the widget exists in the layout, then do not add a new one.
And if does not exist, add a new one.
How to do it?
void MainWindow::slotPush1()
{
if <there is no infoClient> ui->verticalLayout_3->addWidget(new infoClient(this));
}
Just add all your widgets into the layout and use QWidget::hide() , QWidget::show() when needed. For more complex situations you can use The State Machine Framework.
Qt uses a layout-based approach to widget management. Widgets are arranged in the optimal positions in windows based on simple layout rules, leading to a consistent look and feel. Custom layouts provide more control over the positions and sizes of child widgets.
Widgets are the primary elements for creating user interfaces in Qt. Widgets can display data and status information, receive user input, and provide a container for other widgets that should be grouped together. A widget that is not embedded in a parent widget is called a window.
Few points:
layout()
is not null) or widgets (widget()
is not null). In the end you have a tree of layout items.So You need to do a search from the parent 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;
}
Use QObject::findChild to find a child by its name. For instance:
void MainWindow::slotPush1()
{
if (ui->verticalLayout_3->findChild<QWidget*>("infoClient")) // your code to add it here
}
Note: findChild is a template function. If you're not familiar with template functions, just know that you pass the type of object you want to find (in your example, it looks like you could use ui->verticalLayout_3->findChild<infoClient*>("infoClient")
). If you want to find a QWidget, or anything that inherits from QWidget, you can just use findChild<QWidget*>()
and you'll be safe.
There is no mechanism within Qt that will perform the check that you are looking for. You will have to implement it yourself:
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;
}
Despite what I've suggested above, I don't really recommend it. It makes more sense to store whether or not you've added infoClient to your layout as an independent boolean within your program somewhere. Querying the contents of layouts in this manner is somewhat unusual, and is messier than just using a bool
.
I agree with Tom Panning's solution to find your child with the QObject::findChild()
method.
But adding a Widget to QLayout will reparent it to the layout's parent. So you'll have to find it by calling it with the MainWindow
object like that:
void MainWindow::slotPush1()
{
if (this->findChild<QWidget*>("infoClient")) {
// ...
}
}
If your infoClient widget was added in the QtDesigner, you won't have problems with this solution. The designer sets per default the object name. If the infoClient was added to the layout in your code, you have to set the object name explicitly, otherwise you won't be able to find it because its name is empty: (Assuming, m_client is a member variable of MainWindow)
void MainWindow::createWidgets()
{
if (infoClientShouldBeAdded) {
m_client = new infoClient(this);
m_client->setObjectName("infoClient");
ui->verticalLayout_3->addWidget(m_infoClient);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With