1

QTreeWidgetItem クラスの setItemWidget() 関数を使用して設定したウィジェットが埋め込まれた QTreeWidgetItems がたくさんあります。

問題は、ドラッグ/ドロップまたはその他の手段を使用して QTreeWidgetItem を移動するたびに、以前に設定した埋め込みウィジェットが消えることです。さまざまなフォーラムで、他の人がこの同じ問題を抱えているのを見てきました(以下のリンクを参照)

http://www.qtcentre.org/threads/40500-QTreeWidget-setItemWidget%28%29-item-disappears-after-moving-item

可能な解決策はありますか?

4

1 に答える 1

2

問題はQTreeWidgetの実装が原因です。モデル内でアイテムを移動すると、古い位置にあるアイテムが削除され、新しい位置に再作成されます。次の 3 つのことを確認する必要があります。

  1. アイテムが削除されたときに埋め込みウィジェットが削除されないようにレスキューします。
  2. アイテムを追跡し、アイテムに属するウィジェットを選択できるように、アイテムにいくつかの情報を添付します。
  3. アイテムの移動後にウィジェットを再挿入します。

これが概念実証の実装です。Tree_widget_keeper_wrapper1 番目の目的をsetItemWidget保証し、 の再実装により 2 番目の目的を保証し、rows_insertedスロットにより 3 番目の目的を保証します。動作することをテストしましたが、実際のプロジェクトで使用する前に改善する必要があります。Qt::UserRole構成可能な役割に変更する必要があります。モデル自体で使用されていないロールを使用する必要があります。読みやすくするためにすべての実装をクラス宣言に入れましたが、実際のコードではそれらを分離する必要があります。

class Tree_widget_keeper_wrapper : public QWidget {
  Q_OBJECT
public:
  Tree_widget_keeper_wrapper(QWidget* child) {
    _child = child;
    QVBoxLayout* layout1 = new QVBoxLayout(this);
    layout1->setContentsMargins(0, 0, 0, 0);
    layout1->addWidget(_child);
  }

  ~Tree_widget_keeper_wrapper() {
    if (_child->parent() == this) {
      _child->hide();
      _child->setParent(0);
    }
  }

private:
  QWidget* _child;

};

class Fixed_tree_widget : public QTreeWidget {
  Q_OBJECT
public:
  Fixed_tree_widget(QWidget* parent) : QTreeWidget(parent) {
    connect(model(), SIGNAL(rowsInserted(QModelIndex,int,int)),
            this, SLOT(rows_inserted(QModelIndex,int,int)));
  }

  void setItemWidget(QTreeWidgetItem* item, int column, QWidget* widget) {
    QTreeWidget::setItemWidget(item, column, new Tree_widget_keeper_wrapper(widget));
    item->setData(column, Qt::UserRole, all_widgets.count());
    all_widgets << widget;
  }

private:
  QWidgetList all_widgets;

private slots:
  void rows_inserted(QModelIndex parent, int start, int end) {
    for(int column = 0; column < model()->columnCount(parent); column++) {
      for(int row = start; row <= end; row++) {
        QModelIndex index = model()->index(row, column, parent);
        QVariant data = model()->data(index, Qt::UserRole);
        if (data.type() == QVariant::Int) {
          int i = data.toInt();
          QTreeWidgetItem* item = itemFromIndex(index);
          if (item && i >= 0 && i < all_widgets.count()) {
            setItemWidget(item, column, all_widgets[i]);
            all_widgets[i]->show();
          }

        }
      }
    }
  }

};

モードに対してテストしInternalMove、マウスでアイテムをドラッグしました。場合によっては、他のモデルの信号をリッスンする必要がある場合もあります。

于 2014-08-31T00:28:40.257 に答える