选择父项复选框时如何在QTreeView中选择子项复选框

选择父项复选框时如何在QTreeView中选择子项复选框,qt,qtreeview,Qt,Qtreeview,当我选择/取消选择其父项的QCheckBox时,我想选择/取消选择所有子项的QCheckBox 我从QTreeView继承并检测何时选择了QCheckBox,然后调用函数执行选择/取消选择过程 这是我的代码: #ifndef MYQTREEVIEW_H #define MYQTREEVIEW_H #include <QTreeView> #include <QMouseEvent> #include <QDebug> #include <QStanda

当我选择/取消选择其父项的QCheckBox时,我想选择/取消选择所有子项的QCheckBox

我从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未选中/取消选中时,代码可能不起作用


提前感谢。

我相信操纵treeview项目的最佳方法是通过模型。看起来您正在使用QStandardItemModel;因此,您可以重写模型的方法,并重置作为参数传递到此方法的项索引的子项值。下面是一个小例子:

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);

希望这能有所帮助,我相信操纵treeview项目的最好方法是通过模型。看起来您正在使用QStandardItemModel;因此,您可以重写模型的方法,并重置作为参数传递到此方法的项索引的子项值。下面是一个小例子:

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);

希望这对您有所帮助,在我看来,您应该在重置CheckBoxIndex之前调用QTreeView::mousePressEventevent,让QTreeView更新checkState。

在我看来,您应该在重置CheckBoxIndex之前调用QTreeView::mousePressEventevent,让QTreeView更新checkState。

覆盖mouseReleaseEvent而不是MousePresseEvent


因为当鼠标释放而不是按下鼠标时,检查状态会改变

覆盖mouseReleaseEvent而不是mousePressEvent

因为当鼠标释放而不是按下鼠标时,检查状态会改变