2013-07-17 31 views
10

(Tôi sử dụng Qt 4.7, Windows 7, 64bit).Giới thiệu về xóa, xóa tiện ích và bố cục trong Qt 4

Tôi đã tạo bảng tùy chỉnh. Mỗi hàng là một bố cục nằm ngang với các widget. Các hàng được giữ trong một Danh sách cho phép truy cập dễ dàng và các trẻ em cũng vậy. Các hàng cũng được thêm vào trong phụ huynh.

Nếu tôi đổi kích thước tiện ích con, tôi tính toán kích thước mới, xóa mọi thứ và tạo lại.

Vấn đề của tôi là tôi không muốn xóa bất kỳ tiện ích nào. Chỉ khi tôi dọn bàn, tôi làm.

Vì tôi có các tiện ích bên trong QList và bên trong bố cục gốc, Làm thế nào tôi có thể xóa tất cả các tiện ích trong mỗi hàng, xóa tất cả bố cục và sau đó thêm các bố cục đó vào bố cục mới?

Nếu tôi làm: takeAt (0) cho mọi phần tử bên trong mỗi bố cục, tôi có một QLayoutItem với một tiện ích bên trong ... Làm cách nào để xóa layoutItem mà không xóa tiện ích? .... Làm cách nào để xóa tiện ích con mà không giết chết nó, không có vấn đề nếu nó ở trong cha mẹ hoặc đứa trẻ? Vì có nhiều phương thức xóa: removeItem, removeWidget ... trong layout, nhưng không dùng takeWidget ... chỉ cần takeAt() và nó cho Qlayoutitem.

Tôi đã thử một số cách, nhưng tôi vẫn thấy các tiện ích bất kể điều gì đã xảy ra với chúng.

câu hỏi về vấn đề này:

  • Khi nào một widget được xóa? Nếu tôi takeWidget (index) từ một layout, nó có bị xóa một thời gian không? nó xảy ra nếu tôi có một con trỏ đến nó trong một danh sách khác?

  • removeAt (index) thực hiện phương pháp xóa của tiện ích con?

Trả lời

19

Ok. Tôi đã làm việc đó. Hãy để tôi giải thích cách xóa, giữ các tiện ích hoạt động.

Một tiện ích được biết bởi bố cục gốc của nó.Và bạn loại bỏ nó thông qua cách bố trí. Bằng cách thực hiện:

layout()->removeAt(widget); 
delete widget; 

Nếu bạn sử dụng takeAt (index) trong QLayout (hoặc con của nó), nó cung cấp cho bạn một QLayoutItem. Để truy cập vào widget bên trong, chỉ cần sử dụng widget(). Nhưng không có cách nào để xóa tiện ích mà không xóa nó. Vì vậy, phương pháp này không hợp lệ.

Trong Documents nó nói một cách để xóa các yếu tố:

QLayoutItem *child; 
while ((child = layout->takeAt(0)) != 0) { 
    ... 
    delete child; 
} 

Một điều đặc biệt cần lưu ý trong Qt là như sau: Nếu bạn có một cây hyerarchy của bố trí, thêm vào với addLayout () bố cục bên trong, bất kể phụ tùng của bạn được chèn vào bao nhiêu, bạn có thể xóa nó khỏi bố trí con hoặc bố cục bất kỳ của bố cục, nếu đường dẫn cây từ bố cục và mục này được tạo từ bố cục con.

Điều đơn giản nhất là giữ một danh sách các con trỏ tới tất cả các mục, trong một bảng tùy chỉnh. Khi xóa bảng để tạo lại nó, chỉ cần làm điều này bên trong tiện ích của bạn:

CustomTableItem* item; 
    while (!items_.isEmpty() && ((item = items_.takeFirst()) != 0)){ 
    layout()->removeWidget(item); 
    delete item; // It works no matter where the item is 
    } 

    items_.clear(); // clear the list afterwards. 

Và nó hoạt động hoàn hảo, tự cập nhật bố cục. Nếu bạn muốn giữ nguyên tố, chỉ cần bỏ qua mục "xóa mục"; và sử dụng chúng sau đó.

Điều quan trọng cần lưu ý là chức năng "xóa" khác nhau hoạt động khác nhau (như tôi hiểu trên Qt Documents) trong QList hoặc các tiện ích tương tự và trong QLayout. Trong QList, removeAt thực sự loại bỏ đối tượng.

(Qt 4.7 QList Documents) "Loại bỏ mặt hàng đó ở vị trí chỉ số i. I phải là một vị trí chỉ số có giá trị trong danh sách (ví dụ: 0 < = i < size())."

Trong QLayout, removeWidget hoặc removeItem không xóa mục/tiện ích, bạn có trách nhiệm xóa nó, như tôi đã làm trước đây.

(Qt 4.7 QLayout Documents) "Gỡ bỏ các widget widget từ cách bố trí. Sau cuộc gọi này, đó là trách nhiệm người gọi để cung cấp cho các phụ tùng một hình học hợp lý hoặc đặt widget trở lại vào một bố cục."

Hy vọng điều đó sẽ hữu ích. Nếu bạn thấy bất kỳ lỗi nào, bạn có thể cho tôi biết và tôi chỉnh sửa câu trả lời !.

Thông tin thêm về xóa ở đây: Other stackoverflow post

+0

bố cục() -> removeAt (tiện ích con); CHỈ tồn tại cho QGraphicsLayout. Những gì bạn có nghĩa là có lẽ bố trí() -> removeWidget (widget); – Bim

+0

Đó cũng là những gì bạn có thể làm để xóa tiện ích con khỏi bố cục KHÔNG xóa nó.Nếu bạn không có con trỏ widget, hãy làm như sau: QLayoutItem * item = layout-> itemAt (0); QWidget * widget = item-> widget(); if (widget! = NULL) { bố cục-> removeWidget (tiện ích con); // nếu bạn muốn xóa tiện ích con, hãy làm: widget-> setParent (NULL); xóa tiện ích con; } (định dạng không hoạt động, nhưng bạn có ý tưởng ...) – Bim

+0

FYI: Điều này không hợp lệ trong Python vì bạn cũng phải xử lý đối tượng C++ bên trong. – darkgaze

6

Một widget trong Qt là một thường xuyên đối tượng C++ và có thể bị xóa với toán tử C++ delete như bất kỳ đối tượng khác:

delete myWidget; 

Trong Qt luôn luôn có một mối quan hệ cha-con giữa các widget. Khi phụ huynh bị hủy, nó sẽ xóa tất cả các con của nó. Thông thường, bạn không cần phải suy nghĩ rõ ràng về việc xóa bất kỳ tiện ích con nào nhưng tiện ích con cấp cao nhất, tức là cửa sổ và hộp thoại. Qt sẽ chăm sóc xóa bất kỳ tiện ích con nào.

QList::removeAt(int) không xóa đối tượng bị xóa, chỉ xóa đối tượng khỏi danh sách. Nếu bạn cũng muốn xóa các đối tượng bạn sẽ phải làm một cái gì đó như:

delete myList.takeAt(0); 

này áp dụng cho tất cả các chức năng như removeAt(int), takeAt(int), takeFirst(), vv Họ không bao giờ xóa các đối tượng, họ chỉ loại bỏ chúng khỏi container (danh sách, bố trí, scrollarea, vv). Trong hầu hết các trường hợp, quyền sở hữu của widget sau đó được chuyển sang người gọi, (người gọi sẽ chịu trách nhiệm xóa tiện ích khi ngắt mối quan hệ cha-con), nhưng không cho rằng đây luôn là trường hợp, luôn đọc tài liệu của hàm .

+0

Cảm ơn! Nhưng những gì về vấn đề cụ thể của tôi: Tôi có một QBoxLayout. Tôi làm: takeAt (int) để lấy một phần tử. Nó không phải là một widget, mà là một QLayoutItem. Để sử dụng tiện ích tôi sử dụng. Hàm widget (void). Nhưng tiện ích vẫn ở bên trong. Làm thế nào để tôi lấy ra các widget và xóa LayoutItem đó? Không có chức năng cho điều đó! – darkgaze

+0

FYI Điều này không hợp lệ trong Python. Bạn phải chăm sóc đối tượng C++ bên trong. – darkgaze

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