เปิด QDialog เพียงอินสแตนซ์เดียวด้วย show() และ Object จะถูกลบด้วยหากฉันปิด QDialog

ใน Qt ฉันกำลังเปิดหน้าต่าง QDialog ทุกครั้งที่ฉันคลิกบางรายการฉันกำลังทำสิ่งใหม่ ฉันต้องการแน่ใจว่าฉันกำลังเปิด QDialog เพียงอินสแตนซ์เดียวสำหรับแต่ละรายการที่ฉันคลิก:

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 ไว้หรือไม่ คำถามที่สองของฉันคือ: แต่ละครั้งที่ฉันปิดหน้าต่าง QDialog โดยปิด () วัตถุ pGroupDialogContainer ที่รับผิดชอบในการเปิดมันคือ destroyer ed หรือไม่ หรือฉันต้องลบมันออกเมื่อฉันตรวจพบว่า QDIalog ปิดไปแล้ว?


person user63898    schedule 02.06.2011    source แหล่งที่มา
comment
คุณช่วยอธิบายเพิ่มเติมอีกเล็กน้อยเกี่ยวกับสิ่งที่ GroupDialogContainer กำลังทำอยู่ หรือโพสต์โค้ดได้   -  person Abhijith    schedule 02.06.2011
comment
มันเป็นเพียงคลาสที่สืบทอดมาจาก QDialog   -  person user63898    schedule 02.06.2011
comment
เมื่อเรียกใช้ QDialog->show() UI ของคุณจะถูกบล็อกจนกว่า QDialog จะถูกปิด เว้นแต่คุณจะมีกล่องโต้ตอบแบบไม่มีโหมด ฉันไม่เห็นว่าคุณจะมีปัญหากับกล่องโต้ตอบหลาย ๆ อันอย่างไร   -  person Abhijith    schedule 02.06.2011


คำตอบ (1)


ใช่ คุณควรเก็บรายการกล่องโต้ตอบของคุณไว้เพื่อติดตามว่ารายการใดบ้างที่เปิดอยู่แล้ว หาก GroupID ของคุณเป็น ID เฉพาะของคุณ คุณสามารถดำเนินการดังนี้:

QMap DialogMap;

เป็นโมฆะ foo::treeWidget_itemClicked(QTreeWidgetItem *item,nt คอลัมน์) {
..... 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);

แต่อย่างที่บอกไป คุณยังคงต้องลบกล่องโต้ตอบออกจากแผนที่ ไม่เช่นนั้น คุณจะมีตัวชี้ที่ไม่ถูกต้องในนั้น และโค้ดของคุณจะยังคงคิดว่ากล่องโต้ตอบนั้นเปิดอยู่

ดังนั้นคุณจะต้องมีสัญญาณบางอย่างจากกล่องโต้ตอบเพื่อระบุว่ากำลังปิด มีสัญญาณที่เสร็จสิ้นแล้ว (int result) ที่ถูกเรียกเมื่อคุณทริกเกอร์ผลลัพธ์:

สัญญาณนี้จะถูกส่งออกมาเมื่อมีการตั้งค่าโค้ดผลลัพธ์ของกล่องโต้ตอบ โดยผู้ใช้หรือโดยการเรียก เสร็จสิ้น() ยอมรับ() หรือ ปฏิเสธ()

แต่คุณสามารถสร้างสัญญาณของคุณเองในกล่องโต้ตอบของคุณได้ตลอดเวลา และส่งสัญญาณเมื่อมีการเรียก 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());
   }
}

และนั่นมัน

person Liz    schedule 02.06.2011
comment
แค่คิดว่า ... ฟังก์ชั่นการเชื่อมต่อนั้นอยู่ในแต่ละอินสแตนซ์ที่ฉันสร้างขึ้น? ฉันควรวางไว้ที่ไหน? ในฟังก์ชันที่สร้าง pGroupDialogContainer ของ treeWidget_itemClicked? หรือสร้างตัวแปรโกลบอล pGroupDialogContainer และใส่การเชื่อมต่อลงในคอนสตรัคเตอร์หรืออะไร? - person user63898; 03.06.2011
comment
หากคุณสามารถเปิดกล่องโต้ตอบได้มากกว่าหนึ่งรายการในแต่ละครั้ง คุณจะต้องใช้จากที่ที่คุณสร้าง เนื่องจากคุณจะต้องมีการเชื่อมต่อที่ใช้งานได้สำหรับทุกกล่องโต้ตอบที่เปิดอยู่ในปัจจุบัน - person Liz; 03.06.2011