You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QML视图间拖放时如何避免列表出现空白区域?

Answer

First, straight to the point: Using only reparenting (as in the basic Tiles example) won’t automatically make the list rearrange to fill the blank space. Here’s why, and how to fix it:

Why reparenting alone doesn’t work

In the default Tiles example, when you drag a tile from the list to the grid, you’re just changing the item’s parent from the list container to the grid container. However:

  • If your list is a static container (like a Column with hardcoded items) or a ListView/Repeater bound to a model that isn’t updated, the list doesn’t "know" the item is gone. It’ll keep the empty space where the tile was, because the model still includes the item (if using a model) or the container’s child list still has a placeholder (if static).
  • Even if the list detects the item is removed, most Qt Quick container components (like Column, ListView) don’t automatically reflow their remaining items to fill gaps unless their underlying data source (the model) is modified.

The better approach: Use two separate models

To get automatic rearrangement in both the list and grid, you need to tie each view to its own model, and update those models when a drag-and-drop occurs:

  1. Define two models: One for the available tiles in the list (e.g., a ListModel), another for the tiles placed in the grid.
  2. On drag start: Keep track of which tile is being moved.
  3. On drop completion:
    • Remove the tile’s data from the list’s model.
    • Add that data to the grid’s model.
    • The ListView will automatically remove the delegate and shift remaining items up to fill the gap.
    • The GridView will automatically add the new tile to its layout.

Conceptual code snippet

ListModel {
    id: listModel
    ListElement { text: "Button 1"; color: "red" }
    ListElement { text: "Button 2"; color: "blue" }
}

ListModel {
    id: gridModel
}

ListView {
    model: listModel
    delegate: TileDelegate {
        // Handle drag completion
        onDragFinished: {
            if (dropTarget === gridView) {
                listModel.remove(index);
                gridModel.append({ text: text, color: color });
            }
        }
    }
}

GridView {
    id: gridView
    model: gridModel
    delegate: TileDelegate { /* Delegate styling and behavior */ }
}

Can you make reparenting work?

Technically, you could manually adjust the positions of the remaining list items after reparenting, but this is error-prone and not recommended. You’d have to iterate over the list’s children, calculate their new positions, and animate them into place—this bypasses Qt Quick’s built-in layout management and creates unnecessary maintenance work. Using models is the idiomatic Qt Quick way to handle dynamic item lists and grids.

So to sum up: You need two separate models to get the automatic rearrangement behavior you want. Reparenting alone won’t trigger the list to fill the gap without manual intervention.

内容的提问来源于stack exchange,提问作者user4072916

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:42:53