QTreeWidget 实现自动加载目录以树形结构显示,带checkbox,且item,滚动条用qss美化

写这文章是为了对知识的总结与归纳,以便后面忘了好找,也方便初学者可以找到学习资料

#include "TestWidget.h"

TestWidget::TestWidget(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::TestWidgetClass)
{
    ui->setupUi(this);
    ui->treeWidget->clear();    //初始化树形控件
    ui->treeWidget->setHeaderHidden(true);
    int nItemHeight = 20;
    //"QHeaderView::section{background-color{255,255,255};padding:6px 6px;}"

    ui->treeWidget->setStyleSheet(
        "QHeaderView::section{background-color{255,255,255};padding:6px 6px;}"
        "QTreeView{border:1px solid rgb(213,222,234);background-color:rgb(250,252,255);outline:none;}"
        "QTreeView::branch:has-siblings:!adjoins-item{border:none}"
        "QTreeView::branch:has-siblings:adjoins-item{border:none}"
        "QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-siblings{boder-image:none;}"
        "QTreeView::item{height:" + QString::number(nItemHeight) + "px;}"
        "QTreeView::item:hover{background-color:rgb(0,255,0,50)}"
        "QTreeView::item:selected{background-color:rgb(255,0,0,100)}"
        "QTreeWidget::indicator:partiallychecked{boder-image: url(:/TestWidget/Resources/check-normal.png);}"
        "QTreeWidget::indicator:partiallychecked:hover{boder-image: url(:/TestWidget/Resources/check-hover.png);}"
        "QTreeWidget::indicator:checked{border-image: url(:/TestWidget/Resources/selected-normal.png);}"
        "QTreeWidget::indicator:checked:hover{border-image: url(:/TestWidget/Resources/selected-hover.png);}"
        "QTreeWidget::indicator:unchecked{border-image: url(:/TestWidget/Resources/choose-normal.png);}"
        "QTreeWidget::indicator:unchecked:hover{border-image: url(:/TestWidget/Resources/choose-hover.png);}"
        );


      

     QScrollBar *pVLeftScroll = ui->treeWidget->verticalScrollBar();
     pVLeftScroll->setStyleSheet(
         "QScrollBar::vertical {border:1px solid rgb(255,255,255);width: 8px; margin:0px 0px 0px 0px;background-color:rgb(255,255,255);}"
         "QScrollBar::handle:vertical{background-color:rgb(193,206,219);}"
         "QScrollBar::add-line:vertical{width:0px;}"
         "QScrollBar::sub-line:vertical{width:0px;}"
         "QScrollBar::left-arrow:vertical,QScrollBar::right-arrow:vertical{backgroud-color:rgb(235,240,245);}"
         "QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical {background:none;}"
          );
    QScrollBar *pHLeftScroll = ui->treeWidget->horizontalScrollBar();
    pHLeftScroll->setStyleSheet(
          "QScrollBar::horizontal {border:1px solid rgb(255,255,255);height:8px;margin:0px 1px 0px 1px;background-color:rgb(255,255,255)}"
          "QScrollBar::handle:horizontal{background-color:rgb(193,206,219);min-width:10px;}"
          "QScrollBar::add-line:horizontal{width:0px;}"
          "QScrollBar::sub-line:horizontal{width:0px;}"
          "QScrollBar::left-arrow:horizontal,QScrollBar::right-arrow::horizontal{background-color:rgb(235,240,245);}"
          "QScrollBar::add-page:horizontal,QScrollBar::sub-page:horizontal {background:none;}"
          );

    QString rootpath = "C:\\Users\\Administrator\\Desktop\\setups";
    QTreeWidgetItem* root = new QTreeWidgetItem(ui->treeWidget);
    root->setIcon(0, QIcon(":/TestWidget/Resources/folder.png"));
    root->setText(0, rootpath);    //树形控件显示的文本信息
    root->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);   //设置树形控件子项的属性
    root->setCheckState(0, Qt::Unchecked); //初始状态没有被选中

    init(root, rootpath);
    connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(treeItemChanged(QTreeWidgetItem*, int)));

    ui->treeWidget->setItemsExpandable(true);
    ui->treeWidget->expandAll();

}
TestWidget::~TestWidget()
{
    delete ui;
}

QFileInfoList TestWidget::init(QTreeWidgetItem *root, QString path)
{
    /*添加path路径文件*/
    QDir dir(path);          //遍历各级子目录
    QDir dir_file(path);    //遍历子目录中所有文件

    QFileInfoList file_list = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
    QFileInfoList folder_list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);   //获取当前所有目录

    for (int i = 0; i != folder_list.size(); i++)         //自动递归添加各目录到上一级目录
    {
        QString namepath = folder_list.at(i).absoluteFilePath();    //获取路径
        QFileInfo folderinfo = folder_list.at(i);
        QString name = folderinfo.fileName();      //获取目录名
        //qDebug()<<name<<endl;

        QTreeWidgetItem* childroot = new QTreeWidgetItem(QStringList() << name);
        childroot->setIcon(0, QIcon(":/TestWidget/Resources/folder.png"));
        childroot->setText(0, name);
        childroot->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
        childroot->setCheckState(0, Qt::Unchecked);
        root->addChild(childroot);              //将当前目录添加成path的子项

        QFileInfoList child_file_list = init(childroot, namepath);          //进行递归
        file_list.append(child_file_list);
        file_list.append(name);
    }

    dir_file.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);        //获取当前所有文件
    dir_file.setSorting(QDir::Size | QDir::Reversed);
    QFileInfoList list_file = dir_file.entryInfoList();
    //qDebug()<<list_file.size()<<endl;

    for (int i = 0; i < list_file.size(); ++i)        //将当前目录中所有文件添加到treewidget中
    {
        QFileInfo fileInfo = list_file.at(i);
        QString name2 = fileInfo.fileName();
        //qDebug()<<name2<<endl;

        QTreeWidgetItem* child = new QTreeWidgetItem(QStringList() << name2);
        child->setIcon(0, QIcon(":/TestWidget/Resources/word.png"));
        child->setText(0, name2);
        child->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);   //设置树形控件子项的属性
        child->setCheckState(0, Qt::Unchecked); //初始状态没有被选中
        root->addChild(child);
    }

    return file_list;
}

void TestWidget::treeItemChanged(QTreeWidgetItem*item, int)
{
    /*得到文件路径*/
    QStringList filepath;
    QTreeWidgetItem *itemfile = item; //获取被点击的item
    //QString itemText = item->text(0);

    while (itemfile != NULL)
    {
        filepath << itemfile->text(0); //获取itemfile名称
        itemfile = itemfile->parent(); //将itemfile指向父item
    }

    QString strpath;
    for (int i = (filepath.size() - 1); i >= 0; i--) //QStringlist类filepath反向存着初始item的路径 //将filepath反向输出,相应的加入’/‘
    {
        strpath += filepath.at(i);
        if (i != 0)
            strpath += "\\";
    }
    QFileInfo fileInfo(strpath);
    //qDebug()<<strpath<<endl;

    //节点处理
    if (Qt::Checked == item->checkState(0))
    {
        // QTreeWidgetItem* parent = item->parent();
        int count = item->childCount(); //返回子项的个数
        if (count > 0)
        {
            for (int i = 0; i < count; i++)
            {
                item->child(i)->setCheckState(0, Qt::Checked);
            }
            updateParentItem(item);
        }
        else
        {
            updateParentItem(item);
            if (fileInfo.isFile())   //++
            {
                 ui->listWidget->addItem(strpath);
                ui->listWidget->scrollToBottom();
            }
        }
    }
    else if (Qt::Unchecked == item->checkState(0))
    {
        int count = item->childCount();
        if (count > 0)
        {
            for (int i = 0; i < count; i++)
            {
                item->child(i)->setCheckState(0, Qt::Unchecked);
            }
            updateParentItem(item);
        }
        else
        {
            updateParentItem(item);
            if (fileInfo.isFile())   //--
            {
                 QList<QListWidgetItem*> list;
                 list = ui->listWidget->findItems(strpath, Qt::MatchCaseSensitive);
                 QListWidgetItem* sel = list[0];
                 int r = ui->listWidget->row(sel);
                 QListWidgetItem* item = ui->listWidget->takeItem(r);
                 ui->listWidget->removeItemWidget(item);
                 delete item;
 
                 ui->listWidget->scrollToBottom();
            }
        }
    }
}

void TestWidget::updateParentItem(QTreeWidgetItem* item)
{
    QTreeWidgetItem *parent = item->parent();
    if (parent == NULL)
    {
        return;
    }
    int selectedCount = 0;
    int childCount = parent->childCount();
    for (int i = 0; i < childCount; i++) //判断有多少个子项被选中
    {
        QTreeWidgetItem* childItem = parent->child(i);
        if (childItem->checkState(0) == Qt::Checked)
        {
            selectedCount++;
        }
    }
    if (selectedCount <= 0)  //如果没有子项被选中,父项设置为未选中状态
    {
        parent->setCheckState(0, Qt::Unchecked);
    }
    else if (selectedCount > 0 && selectedCount < childCount)    //如果有部分子项被选中,父项设置为部分选中状态,即用灰色显示
    {
        parent->setCheckState(0, Qt::PartiallyChecked);
    }
    else if (selectedCount == childCount)    //如果子项全部被选中,父项则设置为选中状态
    {
        parent->setCheckState(0, Qt::Checked);
    }
}

效果图如下:

可以下载源代码学习,下载网址:

https://download.csdn.net/download/thefront/10412843
————————————————
版权声明:本文为CSDN博主「翼之痕」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/slfkj/article/details/103179600

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值