8

ウィジェットがレイアウト内にあるかどうかを確認するにはどうすればよいですか?ウィジェットが含まれる場合と含まれない場合があるレイアウトがあります。

  • ウィジェット名:infoClient
  • レイヤー名: verticalLayout_3

ウィジェットがレイアウトに存在するかどうかを確認する必要があります。その後、新しいウィジェットを追加しないでください。
また、存在しない場合は、新しいものを追加します。
どうやってするの?

void MainWindow::slotPush1()
{
    if <there is no infoClient> ui->verticalLayout_3->addWidget(new infoClient(this));
}
4

5 に答える 5

3

いくつかのポイント:

  • レイアウト内のウィジェットの親は、最上位のレイアウトを含むウィジェットです
  • レイアウトはネストできます。
  • レイアウトにはアイテム ( QLayoutItem ) が含まれており、これはレイアウト ( layout()null ではない) またはウィジェット ( null ではない)のいずれか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;
}
于 2012-10-10T08:09:02.383 に答える
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.

于 2012-10-10T01:04:40.807 に答える
2

名前で子を見つけるには、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*>()で安全です。

于 2012-10-10T01:06:25.517 に答える
1

この方法であなたの子供を見つけるためのトム・パニングの解決策に同意しますQObject::findChild(). ただし、ウィジェットを QLayout に追加すると、レイアウトの親に親が変更されます。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);
    }
}
于 2012-10-10T06:13:09.510 に答える