qt使用QTreeWidget实现一个树结构显示数据

 

效果图

qt使用QTreeWidget实现一个树结构显示数据_第1张图片

#include
#include
#include
#include
class TreeView :public QTreeWidget
{
public:
    TreeView(QWidget *pParent = nullptr) :QTreeWidget(pParent) {}
    ~TreeView() {};
};

class TreeFrame :public QFrame
{
    Q_OBJECT
public:
    TreeFrame(QWidget *pParent = nullptr);
    ~TreeFrame();
    void initUI();
    void initWidgetItem();
    void connectSlots();
    //改变选中状态时同步子节点
    void syncChildNodeCheckState(QTreeWidgetItem *parentItem, Qt::CheckState state);
    //改变选中状态时同步父节点
    void syncParentNodeCheckState(QTreeWidgetItem *item);
protected slots:
    //勾选节点的信号
    void itemClicked(QTreeWidgetItem *pItem, int nCol);


private:
    TreeView *m_pTreeView;
    QTreeWidgetItem *m_pWidgetItem;
    QStatusBar *m_pBar;
    const static int m_STypeRole = Qt::UserRole;

    //节点类型
    enum NodeType
    {
        NT_RootNode = 0,
        NT_ChildNode,
        NT_ChildToChild
    };
};

TreeFrame::TreeFrame(QWidget *pParent /*= nullptr*/) :QFrame(pParent)
{
    initUI();
    initWidgetItem();
    connectSlots();
}

TreeFrame::~TreeFrame()
{
    if (m_pTreeView)
    {
        delete m_pTreeView;
        m_pTreeView = nullptr;
    }
    if (m_pWidgetItem)
    {
        delete m_pWidgetItem;
        m_pWidgetItem = nullptr;
    }
}

void TreeFrame::initUI()
{
    this->setWindowTitle("Window Title");
    m_pTreeView = new TreeView(this);
    m_pTreeView->setHeaderHidden(true);
    QVBoxLayout *mainLayout = new QVBoxLayout();
    mainLayout->addWidget(m_pTreeView, 10000);  //弹簧比例放大到10000倍
    mainLayout->setSpacing(14);

    QVBoxLayout* totalLayout = new QVBoxLayout();
    totalLayout->setMargin(0);
    totalLayout->setSpacing(0);
    mainLayout->setContentsMargins(16, 16, 16, 6);
    totalLayout->addLayout(mainLayout, 1);
    m_pBar = new QStatusBar;
    m_pBar->setFixedHeight(15);// 高度不能小于15个像素
    m_pBar->setProperty("transparent", true);// 一定要设置属性
    totalLayout->addWidget(m_pBar);
    this->setLayout(totalLayout);
    this->setMaximumHeight(200);
    this->setMinimumWidth(100);

}

void TreeFrame::initWidgetItem()
{
    m_pWidgetItem = new QTreeWidgetItem();
    m_pWidgetItem->setText(0, "All Tree");
    m_pWidgetItem->setCheckState(0, Qt::Unchecked);
    m_pWidgetItem->setData(0, m_STypeRole, NT_RootNode);
    m_pTreeView->addTopLevelItem(m_pWidgetItem);
                            //模拟数据,随便写的
    for (int i = 0; i < 5; ++i)
    {
        QTreeWidgetItem *pItem = new QTreeWidgetItem();
        pItem->setText(0, "ChildeOne");
        pItem->setFlags(pItem->flags() | Qt::ItemIsUserCheckable);
        pItem->setCheckState(0, Qt::Unchecked);
        pItem->setData(0, m_STypeRole, NT_ChildNode);
        m_pWidgetItem->addChild(pItem);
        for (int j = 0; j < 5; ++j)
        {
            //节点下还有节点
            QTreeWidgetItem *pItemChild = new QTreeWidgetItem();
            pItemChild->setText(0, "ChildeTwo");
            pItemChild->setFlags(pItemChild->flags() | Qt::ItemIsUserCheckable);
            pItemChild->setCheckState(0, Qt::Unchecked);
            pItemChild->setData(0, m_STypeRole, NT_ChildToChild);
            pItem->addChild(pItemChild);
        }
    }
    m_pTreeView->expandAll();  //展开所有节点
}

void TreeFrame::connectSlots()
{
    connect(m_pTreeView, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *, int)));
}

void TreeFrame::syncChildNodeCheckState(QTreeWidgetItem *parentItem, Qt::CheckState state)
{
    if (parentItem != NULL && !parentItem->isHidden())
    {
        parentItem->setCheckState(0, state);
        for (int i = 0; i < parentItem->childCount(); i++)
        {
            syncChildNodeCheckState(parentItem->child(i), state);
        }
    }
}

void TreeFrame::syncParentNodeCheckState(QTreeWidgetItem *item)
{
    if (!item)
        return;

    QTreeWidgetItem *pParentItem = item->parent();
    if (!pParentItem)
        return;

    int nCheckedNum = 0;
    Qt::CheckState eState = Qt::Unchecked;
    //遍历节点改变节点选中状态
    for (int i = 0; i < pParentItem->childCount(); i++)
    {
        switch (pParentItem->child(i)->checkState(0))
        {
        case Qt::Checked:
            eState = Qt::PartiallyChecked;
            nCheckedNum++;
            break;
        case Qt::PartiallyChecked:
            eState = Qt::PartiallyChecked;
            break;
        case Qt::Unchecked:
            break;
        default:
            break;
        }
    }
    if (nCheckedNum == pParentItem->childCount())
    {
        eState = Qt::Checked;
    }
    pParentItem->setCheckState(0, eState);

    //同步一下节点状态
    syncParentNodeCheckState(pParentItem);
}

void TreeFrame::itemClicked(QTreeWidgetItem *pItem, int nCol)
{
    if (nCol != 0)
        return;

    Qt::CheckState eState = pItem->checkState(nCol);
    //子节点同步选择状态
    if (eState == Qt::Unchecked)
    {
        syncChildNodeCheckState(pItem, Qt::Unchecked);
    }
    else if (eState == Qt::Checked)
    {
        syncChildNodeCheckState(pItem, Qt::Checked);
    }
    //父节点同步
    syncParentNodeCheckState(pItem);
}

 

#include "qtWidget.h"
#include
#include "treeView.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TreeFrame Frame;
    Frame.show();
    return a.exec();
}

 

 

你可能感兴趣的:(Qt,界面,C++,qt,树结构,界面设计)