1

Qt では、アイテムをクリックするたびに QDialog ウィンドウを開き、 new でそれを実行しています。クリックしたアイテムごとに QDialog のインスタンスを 1 つだけ開いていることを確認したいのです。

void foo::treeWidget_itemClicked(QTreeWidgetItem *item,nt column)                                               
    .....
    QString groupID = item->data(0, Qt::UserRole).toString();
    QString groupName = item->text(0);
    GroupDialogContainer* pGroupDialogContainer = new GroupDialogContainer(groupID,                                                                               groupName,                                                                                   this);

    pGroupDialogContainer->show();

}

class GroupDialogContainer : public QDialog
{
    Q_OBJECT


public:
    GroupDialogContainer(QString GroupId,QString GroupName,QWidget *parent=0); 
    GroupDialogContainer(QWidget *parent=0);
    virtual ~GroupDialogContainer();
    Ui::GroupDialog ui;

public slots:
    void closeEvent(QCloseEvent *event);
};

GroupDialogContainer のある種のハッシュまたはベクトルを保持する必要がありますか? また、私の2番目の質問は、QDialogウィンドウをclose()で閉じるたびに、それを開く責任があったオブジェクトpGroupDialogContainerが破棄されますか?または、QDIalog が閉じたことを検出したときに削除する必要がありますか?

4

1 に答える 1

1

はい、ダイアログの何らかのリストを保持して、どのダイアログが既に開いているかを追跡する必要があります。GroupID が一意の ID である場合、次のようにすることができます。

QMap DialogMap;

void foo::treeWidget_itemClicked(QTreeWidgetItem *item,nt column) {
..... QString groupID = item->data(0, Qt::UserRole).toString();

if (! DialogMap.contains(groupID))
{
  //  Popup the dialog and add it to map
  ...
  DialogMap.insert(groupID, pGroupDialogContainer);
}

}

さて、他の部分です。最も重要なことは、ダイアログを閉じたときにマップからアイテムを削除する必要があるということです。次に、ダイアログを削除するか、次のように、ダイアログを閉じるときにダイアログ自体を削除することをお勧めします。

 // set automatic deletion of object on close
 setAttribute(Qt::WA_DeleteOnClose);

しかし、私が言ったように、マップからダイアログを削除する必要があります。そうしないと、そこに不適切なポインターが含まれ、コードはダイアログがまだ開いていると認識します。

そのため、ダイアログが閉じていることを示すために、ダイアログから何らかのシグナルが必要になります。結果をトリガーするときに呼び出される finished(int result) シグナルがあります。

このシグナルは、ユーザーによって、または done()、accept()、または reject() の呼び出しによって、ダイアログの結果コードが設定されたときに発行されます。

ただし、ダイアログでいつでも独自のシグナルを作成し、ダイアログで closeEvent が呼び出されたときにそれを発行できます。

次に、マップを処理するコードで...

connect( pGroupDialogContainer, SIGNAL(WindowClosed()), this, SLOT(vCleanUpTheMap()));
...
void vCleanUpTheMap()
{
   GroupDialogContainer *pDialog = dynamic_cast<GroupDialogContainer *>(sender());
   if (pDialog)
   {
      // Just to keep things clean disconnect from the dialog.
      disconnect(pDialog);

      //  I am assuming that you can get the key groupID from the dialog
      //  Cause it's a lot easier to remove from a map with the key
      DialogMap.remove(pDialog->GetGroupID());
   }
}

以上です。

于 2011-06-02T21:29:17.693 に答える