2013-04-04 64 views
7

Như một ví dụ rất đơn giản, tôi muốn hiển thị một hộp thoại trong Qt khi tôi nhấn một nút. Các mô hình thông thường cho điều này (trong ứng dụng Tôi hiện đang làm việc trên) có vẻ là như sau:Làm thế nào để hiển thị một cửa sổ trong Qt và xóa nó ngay sau khi nó đóng cửa?

class MainWindow { 
    ... 
private slots: 
    buttonClicked(); 
    ... 
private: 
    ChildWindow * childWindow; 
} 

MainWindow::MainWindow(QWidget * parent) : QWidget(parent) { 
    ... 
    childWindow = new ChildWindow(this); 
    ... 
} 

MainWindow::buttonClicked() { 
    childWindow.show(); 
} 

Đến từ .NET và Windows Forms (và bởi vì tôi không cần truy cập vào đối tượng mà từ nơi khác trong lớp) mẫu sau là quen thuộc hơn với tôi:

button1_Clicked(object sender, EventArgs e) { 
    ChildWindow f = new ChildWindow(); 
    f.Show(); 
} 

biến địa phương có nghĩa là tôi không có thêm một instance field và cũng là cửa sổ sẽ không nán lại xung quanh trong bộ nhớ cho lâu hơn nữa hơn mức cần thiết . Một bản dịch trực tiếp của C++ sẽ là một chút xấu xí bởi vì sẽ không có ai rõ ràng sau đó. Tôi đã thử những điều sau:

  1. shared_ptr. Không may mắn, cửa sổ là delete d ngay khi phương thức kết thúc có nghĩa là cửa sổ mới xuất hiện trong một giây và biến mất lần nữa. Không tốt lắm.

  2. exec() thay vì show(). Điều này sẽ làm việc cho các hộp thoại phương thức, nhưng tài liệu dường như ngụ ý rằng nó cũng dừng vòng lặp sự kiện và bạn nên gọi QApplication::processEvents() thường xuyên nếu nó vẫn cần được cập nhật. Tôi hiểu rất ít ở đây nhưng tôi đoán nó cũng không quá đẹp.

  3. deleteLater(). Đáng buồn thay, chỉ hiển thị một cửa sổ không chặn deleteLater để nó biến mất ngay khi nó xuất hiện.

Có tùy chọn tốt để chỉ dọn dẹp sau khi cửa sổ đóng khi đóng cửa sổ không?

Trả lời

12
childWindow->setAttribute(Qt::WA_DeleteOnClose); 

Cũng lưu ý rằng gọi exec() sẽ chặn thực hiện các vòng lặp sự kiện kêu gọi, nhưng sẽ đẻ trứng lặp sự kiện riêng của mình, vì vậy không có cuộc gọi đến processEvents() cần thiết.

+0

Tôi không thể tìm thấy lời khuyên đó cho 'exec' một lần nữa ở bất cứ đâu trong tài liệu, có thể là nó chỉ nằm trên một số blog ngẫu nhiên có giá trị đáng ngờ. Và cảm ơn cho thuộc tính. Tôi đã tìm kiếm ít nhất một giờ (+ thời gian xây dựng cho các thí nghiệm) cho đến khi tôi vấp vào ý tưởng để chỉ kết nối tín hiệu 'hoàn thành' (không tối ưu nhưng đủ cho mục đích của tôi). – Joey

+0

Nó thực sự được ghi lại khá rõ ràng trong tệp .cpp này http://qt.gitorious.org/qt/qt/blobs/4.8/src/gui/dialogs/qdialog.cpp#line562;) – Chris

+0

Tôi đã đề cập đến những gì tôi đã viết trong câu hỏi liên quan đến 'processEvents'. 'Exec' dừng vòng lặp sự kiện cha mẹ là khá rõ ràng, bởi vì nó chặn; cũng phải tạo một cái mới cho hộp thoại. – Joey

2

Bạn có thể kết nối finished() tín hiệu của hộp thoại thứ để khe deleteLater của nó:

ChildWindow * d = new ChildWindow(this); 
connect(d, SIGNAL(finished(int)), d, SLOT(deleteLater())); 
d->show(); 

Bằng cách này nó sẽ được delete d ngay sau khi bạn đóng hộp thoại.

+0

Lưu ý: Tính năng này hoạt động trong trường hợp không cần kết quả hội thoại. Nếu bạn vẫn cần đối số từ 'finished()' thì tôi không biết điều gì xảy ra. Nhưng đối với vấn đề của tôi ở đây là đủ. – Joey

Các vấn đề liên quan