2011-02-27 55 views
1

當我選擇/取消選擇他們父母的物品QCheckBox時,我想選擇/取消選擇所有孩子的物品QCheckBoxs。如何在QTreeView中選擇孩子的物品複選框

我繼承QTreeView並檢測QCheckBox何時被選中,然後我調用函數做選擇/取消選擇過程。

這裏我的代碼:

#ifndef MYQTREEVIEW_H 
#define MYQTREEVIEW_H 

#include <QTreeView> 
#include <QMouseEvent> 
#include <QDebug> 
#include <QStandardItem> 

class MyQTreeView: public QTreeView { 
public: 
    MyQTreeView(QWidget* parent=0): QTreeView(parent){} 
    virtual ~MyQTreeView() {} 

protected: 
    void resettingCheckBox (QModelIndex& parentIndex) { 
     if (! parentIndex.isValid()) 
      return; 

     QString text = parentIndex.data(Qt::DisplayRole).value<QString>(); 
     qDebug() << "parent is: " << text; 

     if (model()->hasChildren(parentIndex)) { 
      for(int i = 0; i < model()->rowCount(parentIndex) ; i++) { 
       QModelIndex childIndex = model()->index(i, 0, parentIndex); 

       if (model()->hasChildren(childIndex)) 
        resettingCheckBox(childIndex); 
       else { 
        QString text = childIndex.data(Qt::DisplayRole).value<QString>(); 
        qDebug() << "child is: " << text; 

        QStandardItem *parentItem = static_cast<QStandardItem*> (parentIndex.internalPointer()); 
        QStandardItem *childItem = static_cast<QStandardItem*> (childIndex.internalPointer()); 

        if (parentItem->checkState() == Qt::Checked) { 
         qDebug() << "child item " << childItem->checkState(); 
         childItem->setCheckState(Qt::Unchecked); 

        } 
        else { 
         qDebug() << "child item " << childItem->checkState(); 
         childItem->setCheckState( Qt::Checked); 
        } 
       } 
      } 
     } 
    } 

    void mousePressEvent (QMouseEvent *event) { 
     QModelIndex index = indexAt(event->pos()); 

     if(index.isValid()) { 
      QStyleOptionButton opt; 
      opt.QStyleOption::operator=(viewOptions()); 
      opt.rect = visualRect(index); 
      QRect rect = style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt); 

      if (rect.contains(event->pos())) { 
       resettingCheckBox(index); 
      } 

      QTreeView::mousePressEvent(event); 
     } 
    } 
}; 

#endif // MYQTREEVIEW_H 

代碼可能不工作時,我選擇/取消選擇父複選框(subchilds未選中/未選中)。

在此先感謝。

回答

2

我相信操縱樹視圖項目的最好方法是通過模型。它看起來像你正在使用QStandardItemModel;因此您可以覆蓋模型的setData方法,並重置作爲參數傳遞給此方法的項目索引的子項目值。下面是一個小例子:

class TestModel : public QStandardItemModel 
{ 
public: 
    TestModel() {} 

    bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) 
    { 
     QStandardItem *item = itemFromIndex(index); 
     for(int i = 0; i < item->rowCount() ; i++) 
     { 
      QStandardItem *childItem = item->child(i); 
      setData(childItem->index(), value, role); 
     } 
     return QStandardItemModel::setData(index, value, role); 
    } 
}; 

這裏的這種模式如何被初始化:

QStandardItemModel* tableModel = new TestModel(); 
QStandardItem* parentItem = tableModel->invisibleRootItem(); 
for (int i = 0; i < 4; ++i) 
{ 
    QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); 
    item->setCheckable(true); 
    parentItem->appendRow(item); 
    parentItem = item; 
} 
treeView->setModel(tableModel); 

希望這會有所幫助,至於

+0

謝謝,它現在的工作。 – 2011-02-28 05:44:40

0

在我看來,你應該resettingCheckBox(index)之前調用QTreeView::mousePressEvent(event),讓QTreeView更新checkState

+0

謝謝,但它不能解決問題 – 2011-02-28 06:05:03

-1

重寫mouseReleaseEvent()而不是mousePressEvent()!

因爲checkState更改鼠標時釋放鼠標 - 按!

相關問題