2014-08-28 11 views
0

QTreeWidgetItem 클래스의 setItemWidget() 함수를 사용하여 설정 한 위젯이 포함 된 QTreeWidgetItems 묶음이 있습니다.QTreeWidgetItem 문제 : setWidgetItem을 사용하여 설정된 항목이 이동 후 표시됩니다.

드래그 앤 드롭 또는 내가 설정 한 내장 된 위젯이 사라지는 다른 방법을 사용하여 QTreeWidgetItem을 이동할 때마다 문제가 발생합니다. 나는 다른 사람이 같은 문제 (아래 링크 참조)

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

모든 가능한 해결책이 있었다 그 다양한 포럼 주위를 보았다?

답변

1

이 문제는 QTreeWidget의 구현으로 인해 발생합니다. 항목이 모델 내에서 이동되면 이전 위치의 항목을 삭제하고 새 위치에서 항목을 다시 만듭니다. 다음과 같은 세 가지 축소 작업이 필요합니다.

  1. 구조가 포함 된 위젯이 삭제되면 삭제되지 않습니다.
  2. 항목에 정보를 첨부하여 항목을 추적하고 항목에 속하는 위젯을 선택할 수 있습니다.
  3. 항목을 이동 한 후 위젯을 다시 삽입하십시오.

다음은 개념 증명입니다. Tree_widget_keeper_wrapper은 1 차 목표를 보장하고, 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 모드에 대해 테스트하고 마우스로 항목을 드래그했습니다. 다른 경우에는 다른 모델의 신호를 청취해야 할 수도 있습니다.