基于Qt QTreeView|QTreeWidget控件使用简单版

303 阅读9分钟

 ​编辑 头文件解析:

这是一个C++代码文件,定义了一个名为MainWindow的类。以下是对每一句的详细解释:

#ifndef MAINWINDOW_H  
#define MAINWINDOW_H  

这是一个条件编译指令,用于避免头文件的重复包含。MAINWINDOW_H是一个宏定义,用于唯一标识这个头文件。

#include <QMainWindow>  
#include <QTreeWidgetItem>  
#include <QStandardItemModel>

#include "dialog.h"  

这些是包含其他头文件的指令。QMainWindowQTreeWidgetItemQStandardItemModel是Qt框架提供的类,用于创建主窗口、树形控件和标准数据模型。dialog.h是另一个头文件的引用。

QT_BEGIN_NAMESPACE  
namespace Ui { class MainWindow; }  
QT_END_NAMESPACE  

这是Qt框架的命名空间声明。Ui是一个命名空间,内部包含一个名为MainWindow的类的前向声明。

enum TYPE  
{  
    TYPE_1,  
    TYPE_2,  
};  

这是一个枚举类型的定义。TYPE是枚举的名称,包含两个枚举值TYPE_1TYPE_2

class QMenu;  

这是一个类的前向声明。QMenu是Qt框架提供的菜单类。

class MainWindow : public QMainWindow  
{  
    Q_OBJECT

public:  
    MainWindow(QWidget *parent = nullptr);  
    ~MainWindow();

private slots:  
    void on_pushButton_clicked();  
    void on_checkBox_root_clicked(bool checked);  
    void on_pushButton_treeVIew_clicked();  
    void on_checkBox_root_2_clicked(bool checked);  
    void on_treeView_clicked(const QModelIndex &index);  
    void on_rb_treeView_clicked();  
    void on_pushButton_title_clicked();

private:  
    Ui::MainWindow *ui;

    QStandardItemModel  *model = nullptr;  
};  

这是MainWindow类的定义。它继承自QMainWindow类,并且使用Q_OBJECT宏进行了标记,以支持Qt的元对象系统。类中声明了一些成员函数和成员变量,包括构造函数、析构函数,以及一些槽函数(用于响应特定的信号)。ui是指向Ui::MainWindow的指针,model是指向QStandardItemModel的指针。

#endif // MAINWINDOW_H  

这是条件编译指令的结束标记,与开头的#ifndef MAINWINDOW_H相对应,用于结束条件编译块。

这段代码定义了一个名为MainWindow的类,该类继承自QMainWindow,并且包含了一些成员函数和成员变量。它与Qt框架相关,用于创建主窗口和处理与主窗口相关的事件和操作。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTreeWidgetItem>
#include <QStandardItemModel>

#include "dialog.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

enum TYPE
{
    TYPE_1,
    TYPE_2,
};


class QMenu;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();
    void on_checkBox_root_clicked(bool checked);
    void on_pushButton_treeVIew_clicked();
    void on_checkBox_root_2_clicked(bool checked);
    void on_treeView_clicked(const QModelIndex &index);
    void on_rb_treeView_clicked();
    void on_pushButton_title_clicked();

private:
    Ui::MainWindow *ui;

    QStandardItemModel  *model = nullptr;
};
#endif // MAINWINDOW_H

源文件解析:

 这段代码是Qt框架下的一个主窗口程序,主要包括了以下几个部分:

  1. 包含头文件:引入了mainwindow.hui_mainwindow.h两个头文件,分别定义了MainWindow类和MainWindow类的UI界面。

  2. 定义构造函数:MainWindow类的构造函数,初始化了一些基本的属性,如父窗口、标题、UI界面等。

  3. 定义析构函数:MainWindow类的析构函数,释放了一些动态分配的内存。

  4. 槽函数:定义了一些槽函数,用于处理各种用户事件,如按钮点击、复选框点击、树视图点击等。

  5. 初始化UI界面:设置了一些UI界面的属性,如树视图的列数、标题、样式等。

  6. 添加右键菜单:为树视图添加了右键菜单,并设置了菜单项的点击事件处理函数。

  7. 设置模型数据:为树视图添加了一些示例数据,包括公司、部门、员工等信息。

  8. 设置默认选中项:设置了树视图的默认选中项。

  9. 响应右键菜单信号:连接了树视图的右键菜单信号,当用户点击右键时,弹出菜单。

  10. 响应添加和删除操作:为添加和删除操作设置了点击事件处理函数。

  11. 设置属视图样式表:为树视图设置了一些样式,如背景色、字体大小、字体颜色等。

  12. 响应标题按钮点击:设置了标题按钮的点击事件处理函数,用于显示一个对话框。

整体来看,这是一个使用Qt框架创建的一个主窗口程序,主要实现了树视图的基本功能,如添加、删除、修改等操作,以及右键菜单功能。同时,也设置了一些UI界面的样式和属性。

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMenu>
#include <QtDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->setWindowTitle("vx公众号搜关注:Qt历险记");
}

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


// 控件 treeWidget
void MainWindow::on_pushButton_clicked()
{
    //qtreewidget 默认的columncount property属性
    /*
    qtreewidget默认的columncount为1.可以通过setcolumncount()把它设置为一个多列的qtreewidget
    */
    ui->treeWidget->setColumnCount(2);
    QTreeWidgetItem* topItem1 = new QTreeWidgetItem(ui->treeWidget);
    topItem1->setText(0, "百度");
    topItem1->setText(1, "蒙牛");
    //为顶层节点添加子节点
    QTreeWidgetItem* subItem1 = new QTreeWidgetItem();
    subItem1->setText(0, "人事部");
    topItem1->addChild(subItem1);

    QTreeWidgetItem* subItem2 = new QTreeWidgetItem();
    subItem2->setText(0, "财务部");
    topItem1->addChild(subItem2);

    ui->treeWidget->addTopLevelItem(topItem1);

    QTreeWidgetItem* topItem2 = new QTreeWidgetItem(ui->treeWidget);
    topItem2->setText(0, "腾讯");
    topItem2->setText(1, "伊利");
    ui->treeWidget->addTopLevelItem(topItem2);

    //ui->treeWidget->setHeaderHidden(true); //隐藏qtreewidget的头部
    QStringList strList;
    strList << "互联网公司" << "食品公司";
    ui->treeWidget->setHeaderLabels(strList); //自定义qtreewidget的头部

   // 设置右键菜单选项
   // 允许右键菜单
   ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
   // 设置菜单
   QMenu *myMenu = new QMenu(ui->treeWidget);
   QAction *add = myMenu->addAction("添加");
   QAction *del = myMenu->addAction("删除");

   // 响应右键菜单信号
   connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this, [=](const QPoint pos){
           auto itemList = ui->treeWidget->selectedItems(); //得到选中的itemList,默认情况下是不可以多选的
           if(itemList.size() < 1) //异常情况下直接返回
           {
               return;
           }
           int type = itemList.first()->type(); //获取选中状态的item的类型
           if(type == TYPE_1) //如果是一级item就弹出菜单栏
           {
               myMenu->exec(ui->treeWidget->mapToGlobal(pos));
           }
       });

   // 响应添加的action点击
   connect(add, &QAction::triggered, this, [=](){
       //添加一个固定的子节点
       QTreeWidgetItem *item = new QTreeWidgetItem();
       item->setText(0, "营销部");
       topItem1->addChild(item);
   });

   // 响应删除的action点击
   connect(del, &QAction::triggered, this, [=](){
       qDebug() << topItem1->childCount();
       if (topItem1->childCount() >= 1)
       {
           QTreeWidgetItem *item = topItem1->child(topItem1->childCount() - 1); // 每次删除最后一个直到删完
           topItem1->removeChild(item);
           delete item;
           item = nullptr;
       }
   });
}

void MainWindow::on_checkBox_root_clicked(bool checked)
{
    ui->treeWidget->setHeaderHidden(checked);
}

// 控件 treeView
void MainWindow::on_pushButton_treeVIew_clicked()
{
    ui->treeView->setSelectionBehavior(QTreeView::SelectRows);			//一次选中整行
    ui->treeView->setSelectionMode(QTreeView::SingleSelection);         //单选,配合上面的整行就是一次选单行
    ui->treeView->setFocusPolicy(Qt::NoFocus);                          //去掉鼠标移到单元格上时的虚线框
    ui->treeView->header()->setStretchLastSection(true);                //最后一列自适应宽度
    //treeView->setHeaderHidden(true);                                  //设置表头隐藏

    model = new QStandardItemModel (this);

    //设置表头
    model->setHorizontalHeaderLabels(QStringList()<<"姓名"<<"性别"<<"年龄");

    //设置model
    ui->treeView->setModel(model);

    //设置展开
    ui->treeView->expandAll();

    // 添加父节点
    QStandardItem *item1 = new QStandardItem("四年级");

    model->setItem(0,0,item1);
    // 设置节点带checkBox
    model->item(0,0)->setCheckable(true);
    model->item(0,0)->setCheckState(Qt::Checked);

    QStandardItem *item00 = new QStandardItem("张三");
    QStandardItem *item10 = new QStandardItem("张四");
    QStandardItem *item20 = new QStandardItem("张五");

    QStandardItem *item01 = new QStandardItem("男");
    QStandardItem *item11 = new QStandardItem("女");
    QStandardItem *item21 = new QStandardItem("男");

    QStandardItem *item02 = new QStandardItem("15");
    QStandardItem *item12 = new QStandardItem("14");
    QStandardItem *item22 = new QStandardItem("16");

    // 添加子节点
    model->item(0,0)->setChild(0,0,item00);
    model->item(0,0)->setChild(1,0,item10);
    model->item(0,0)->setChild(2,0,item20);

    model->item(0,0)->setChild(0,1,item01);
    model->item(0,0)->setChild(1,1,item11);
    model->item(0,0)->setChild(2,1,item21);

    model->item(0,0)->setChild(0,2,item02);
    model->item(0,0)->setChild(1,2,item12);
    model->item(0,0)->setChild(2,2,item22);


    QStandardItem *item2 = new QStandardItem("五年级");
    model->setItem(1,0,item2);

    QStandardItem *item200 = new QStandardItem("李三");
    QStandardItem *item210 = new QStandardItem("李四");
    QStandardItem *item220 = new QStandardItem("李五");

    QStandardItem *item201 = new QStandardItem("男");
    QStandardItem *item211 = new QStandardItem("女");
    QStandardItem *item221 = new QStandardItem("男");

    QStandardItem *item202 = new QStandardItem("15");
    QStandardItem *item212 = new QStandardItem("14");
    QStandardItem *item222 = new QStandardItem("16");

    model->item(1,0)->setChild(0,0,item200);
    model->item(1,0)->setChild(1,0,item210);
    model->item(1,0)->setChild(2,0,item220);

    model->item(1,0)->setChild(0,1,item201);
    model->item(1,0)->setChild(1,1,item211);
    model->item(1,0)->setChild(2,1,item221);

    model->item(1,0)->setChild(0,2,item202);
    model->item(1,0)->setChild(1,2,item212);
    model->item(1,0)->setChild(2,2,item222);

    // 设置默认选中第几行
    QModelIndex index = model->item(0,0)->index();
    ui->treeView->setCurrentIndex(index);


    // 打开右键菜单属性
    ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);

    // 右键菜单
    QMenu *menu = new QMenu(ui->treeView);
    QAction *add = menu->addAction("添加");
    QAction *del = menu->addAction("删除");

    // 响应右键菜单信号槽
    connect(ui->treeView,&QTreeView::customContextMenuRequested,
            this,[=](const QPoint &pos){
        menu->exec(ui->treeView->mapToGlobal(pos));

    });

    // 响应添加的action点击
    connect(add, &QAction::triggered, this, [=](){
        //添加一个固定的子节点
        QStandardItem *item = new QStandardItem("营销部");
        model->item(0,0)->setChild(2,0,item);
    });

    // 响应删除的action点击
    connect(del, &QAction::triggered, this, [=](){
        qDebug() << model->item(0,0)->rowCount();
        if (model->item(0,0)->rowCount() >= 1)
        {
            model->item(0,0)->removeRow(model->item(0,0)->rowCount() -1);
        }
    });

}


void MainWindow::on_checkBox_root_2_clicked(bool checked)
{
    ui->treeView->setHeaderHidden(checked);
}

// 每一个点击的Item(槽)
void MainWindow::on_treeView_clicked(const QModelIndex &index)
{
    if (model == nullptr) return;

    qDebug()<<"on_treeView_clicked = "<<model->itemFromIndex(index)->text();
}

// 设置属视图样式表
void MainWindow::on_rb_treeView_clicked()
{
    const QString styles = "QTreeView\
    {\
        background-color: #5B677A;\
        font-size:17px;\
        color: white;\
    }\
    QTreeView::item:hover\
    {\
        background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);\
        border: 1px solid #bfcde4;\
    }\
    QTreeView::item:hover\
    {\
        background: rgb(69, 187, 217);\
    }\
    QTreeView::item:selected:active\
    {\
        background: rgb(63, 147, 168);\
    }\
    QTreeView::item:selected:!active\
    {\
        background: rgb(63, 147, 168);\
    }\
    QTreeView::branch\
    {\
        background:#5B677A;\
    }\
    ";
    ui->treeView->setStyleSheet(styles);
}

void MainWindow::on_pushButton_title_clicked()
{
    Dialog dialog;
    dialog.exec();
}

mainwindow.ui

​编辑

QTreeView样式表

/* 整个控件样式 */
#treeWidget{
	background:black;
	border:none;
	color: rgb(255, 255, 255);
	font: 18px "黑体" ;
}
/* 简单来说就是一些文本项 */
#treeWidget:item{
	background:gray;
	height:30px;
	color: rgb(255, 255, 255);
	font: 18px "黑体" ;
 	border: 1px solid cyan;
    border-top-color: transparent;
    border-bottom-color: transparent;
}
/* 简单来说就是一些文本项选中时 */
*#treeWidget::item:selected{
	border:none;
	color: rgb(255, 255, 255);
	font: 18px "黑体" ;
	background-color: rgb(255, 0, 0);
}
/* 简单来说就是一些文本项鼠标在上面时 */
#treeWidget::item:hover{
	border:none;
	color: rgb(255, 255, 255);
	font: 18px "黑体" ;
	
	background-color: rgb(0, 255, 0);
}

效果演示

​编辑