当前位置:网站首页>Qt之QTreeView的简单使用(含源码+注释)
Qt之QTreeView的简单使用(含源码+注释)
2022-06-13 03:05:00 【lw只吃亿点.】
一、QTreeView操作示例图
1.节点的添加删除示例图
下图为节点添加删除示例图,其中包含添加顶级节点、添加子节点、移除节点等操作;源码在本文第三节(源码含详细注释)。
2.节点的值的获取与修改
下图为节点对节点值的操作,其中包含获取值、设置值等;源码在本文第三节(源码含详细注释)。
二、QTreeView(个人理解)
这里我们将QTreeView和QTableView对比一下
- 二者都是类似MVC(Model View Controller)模式,其中都包含Delegate,请查看Qt代理的实现(按钮篇)、Qt代理的实现(常规控件篇);
- 二者都使用QStandardItemModel存放数据;
- QTreeView也存在一个继承其QTreeWidget的子类;
- QTreeView会唯一不同的是会操作item的子节点。
三、源码
CMainWindow.h
#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H
#include <QMainWindow>
#include <QStandardItemModel> //数据模型类
namespace Ui {
class CMainWindow;
}
class CMainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit CMainWindow(QWidget *parent = 0);
~CMainWindow();
private slots:
/** * @brief on_getCurNodeDataBtn_clicked 获取当前节点值 */
void on_getCurNodeDataBtn_clicked();
/** * @brief on_setCurNodeDataBtn_clicked 设置当前节点值 */
void on_setCurNodeDataBtn_clicked();
/** * @brief on_addTopNodeBtn_clicked 添加顶级节点 */
void on_addTopNodeBtn_clicked();
/** * @brief on_addChildNodeBtn_clicked 添加子节点 */
void on_addChildNodeBtn_clicked();
/** * @brief on_removeCurNodeBtn_clicked 移除当前节点 */
void on_removeCurNodeBtn_clicked();
private:
Ui::CMainWindow *ui;
QStandardItemModel *m_pModel; //数据模型对象指针
};
CMainWindow.cpp
#include "CMainWindow.h"
#include "ui_CMainWindow.h"
CMainWindow::CMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::CMainWindow)
{
ui->setupUi(this);
//设置窗口标题
this->setWindowTitle("QTreeView的简单使用");
//===============数据模型(QStandardItemModel)===============
//建立数据模型对象空间并指定父对象
m_pModel = new QStandardItemModel(ui->treeView);
//将数据模型设置到树形视图上
ui->treeView->setModel(m_pModel);
//设置水平表头列平均分
ui->treeView->header()->setSectionResizeMode(QHeaderView::Stretch);
//添加列标题
m_pModel->setHorizontalHeaderLabels(QStringList() << "one" << "two");
}
CMainWindow::~CMainWindow()
{
//! 析构函数:
//! 有些小伙伴会发现我没有析构model、m_pFilterModel对象,
//! 那是因为我在获取对象空间的时候指定了父对象,
//! 当其父对象析构时,会先析构其子对象为指针的对象。
delete ui;
}
void CMainWindow::on_getCurNodeDataBtn_clicked()
{
//获取当前行列
QModelIndex curIndex = ui->treeView->currentIndex();
int row = curIndex.row();
int column = curIndex.column();
//当前位置包含-1值返回
if( -1 == row || -1 == column)
{
return;
}
///不获取item的情况///
/// 仅需要获取文本时使用
//! 通过index获取值,默认的data获取的是Qt::DisplayRole的值,
//! 通常来说拿到的值就是显示的值
ui->valueEdit->setText(curIndex.data().toString());
}
void CMainWindow::on_setCurNodeDataBtn_clicked()
{
//获取当前行列
QModelIndex curIndex = ui->treeView->currentIndex();
int row = curIndex.row();
int column = curIndex.column();
//当前位置包含-1值返回
if( -1 == row || -1 == column)
{
return;
}
///需要获取item的情况///
/// \brief curItem 当需要拿到具体item/位置时使用
/// 比如设置item值
QStandardItem *curItem;
int parentRow = curIndex.data(Qt::UserRole + 1).toInt();
//判断顶级节点值选择相应操作
if(-1 == parentRow)
{
curItem = m_pModel->item(row, column);
}
else
{
//获取当前位置的顶级节点
QStandardItem *parentItem = m_pModel->item(parentRow);
//通过顶级节点获取子节点
curItem = parentItem->child(row, column);
}
//获取值编辑框中的值并设置到item上
curItem->setText(ui->valueEdit->text());
}
void CMainWindow::on_addTopNodeBtn_clicked()
{
int index = m_pModel->rowCount();
QList<QStandardItem *> topList;
//链表容器添加顶级节点
topList << new QStandardItem(QString("顶级节点:%1-1").arg(index + 1))
<< new QStandardItem(QString("顶级节点:%1-2").arg(index + 1));
//! 设置Qt::UserRole + n: 用户自定义值
//! 当n值不同时,相当于不同的键值,同理不同键则可设置不同值
//! 此处设置data是为了获取顶级节点值,通过该值判断和做出对应的操作
topList[0]->setData(-1, Qt::UserRole + 1); //设置父节点行,当值为-1时则当前为顶级节点
topList[1]->setData(-1, Qt::UserRole + 1);
//添加顶级节点
m_pModel->appendRow(topList);
}
void CMainWindow::on_addChildNodeBtn_clicked()
{
//获取当前行列
QModelIndex curIndex = ui->treeView->currentIndex();
int row = curIndex.row();
int column = curIndex.column();
int parentRow = curIndex.data(Qt::UserRole + 1).toInt();
//当前行列值包含-1值或当前节点非顶级节点时返回
if( -1 == row || -1 == column || -1 != parentRow)
{
return;
}
//获取指定行的首个item
QStandardItem *curTopItem = m_pModel->item(row);
//为顶级节点添加子节点
QList<QStandardItem *> childList;
childList << new QStandardItem(QString("子节点:%1-1").arg(curTopItem->rowCount()))
<< new QStandardItem(QString("子节点:%1-2").arg(curTopItem->rowCount()));
//设置item的data
childList[0]->setData(row, Qt::UserRole + 1);
childList[1]->setData(row, Qt::UserRole + 1);
//添加子节点
curTopItem->appendRow(childList);
}
void CMainWindow::on_removeCurNodeBtn_clicked()
{
//获取当前行列
QModelIndex curIndex = ui->treeView->currentIndex();
int row = curIndex.row();
int column = curIndex.column();
//当前行列值包含-1值或当前节点非顶级节点时返回
if( -1 == row || -1 == column)
{
return;
}
int parentRow = curIndex.data(Qt::UserRole + 1).toInt();
//判断顶级节点值选择相应的移除操作
if(-1 == parentRow)
{
m_pModel->removeRow(row);
}
else
{
//移除某个子节点需要找到其顶级节点
QStandardItem *parentItem = m_pModel->item(parentRow);
parentItem->removeRow(row);
}
}
四、拓展:上级节点的获取与判断
本文对于节点的判断是通过data设置用户定义值操作的,还有一种方法,是通过获取当前位置的QModelIndex对象获取其父对象的QModelIndex判断,代码如下(下方代码仅适用于本文):
提示:据说以下方法不严谨,如手动指定父类对象时。
void CMainWindow::parentIndex()
{
//获取当前节点的QModelIndex对象
QModelIndex index = ui->treeView->currentIndex();
//获取当前节点父对象的QModelIndex对象
QModelIndex parentIndex = index.parent();
//判断其父节点的行列值,顶级节点的父节点行列值为-1
if(-1 == parentIndex.row() || -1 == parentIndex.column())
{
qDebug() << "当前节点为顶级节点";
}
else
{
qDebug() << "当前节点为子节点";
}
}
总结
QTreeView在判断节点位置时需要注意,并且要设置子节点需要线拿到其父节点才行;每个子节点只有通过其父节点行位置为0的item才可设置;QTreeView设置代理的方式和QTableView一样,需要注意的是,设置的列会贯穿子节点(子节点的对应列同样会生效)。
又是一周,明天继续搬砖了,加油!
相关文章
Qt之QTableView的简单使用(含源码+注释)
Qt代理的实现(按钮篇,含源码+注释)
Qt代理的实现(常规控件篇,含源码+注释)
Qt之QTableView设置多列表头复选框(自定义QHeaderView)、单元格复选框(含源码+注释)
Qt之QSortFilterProxyModel的简单使用(QTableView搜索功能,含源码+注释)
友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 ^o^/)
注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除
边栏推荐
- 开源-校园论坛和资源共享小程序
- My practice of SOA architecture project based on WCF
- Hash table: least recently used cache
- Prometheus install and register services
- Pytorch record: pytorch variables parameter and buffer. self. register_ buffer()、self. register_ parameter()
- Detailed installation tutorial of MATLAB r2019 B-mode ultrasound (complete installation files are attached)
- [life science] DNA extraction of basic biological experiments
- Ijkplayer source code - audio playback
- HEAP[xxx.exe]: Invalid address specified to RtlValidateHeap( 0xxxxxx, 0x000xx)
- Graduation project - campus old thing recycling system based on stm32
猜你喜欢
六款国产飞机专用GPU产品通过鉴定审查
Flutter reports an error type 'Int' is not a subtype of type 'string' wonderful experience
Detailed explanation of UCI datasets and their data processing (with 148 datasets and processing codes attached)
Linked list: the first coincident node of two linked lists
Detailed explanation of handwritten numeral recognition based on support vector machine (Matlab GUI code, providing handwriting pad)
Pycharm installation pyqt5 and its tools (QT designer, pyuic, pyrcc) detailed tutorial
Code d'initialisation de l'arbre binaire
CDN single page reference of indexbar index column in vant framework cannot be displayed normally
Spoon database insert table operation
Linked list: palindrome linked list
随机推荐
Svg filter effect use
Introduction to facial expression recognition system -- offline environment configuration
JVM class loader (2)
MySQL transactions and locks (V)
Special topic I of mathematical physics of the sprint strong foundation program
Ijkplayer source code ---setdatasource
Binary tree initialization code
Flutter reports an error type 'Int' is not a subtype of type 'string' wonderful experience
Stack: daily temperature
On the limit problem of compound function
Wechat applet switch style rewriting
Useful websites for writing papers and studying at ordinary times
Code d'initialisation de l'arbre binaire
Introduction to Kestrel_ Introduction to kestrel web server
Vant框架中关于IndexBar索引栏的CDN单页面引用,无法正常展示
Mvcc and bufferpool (VI)
[data analysis and visualization] key points of data drawing 8- use of circular bar chart
Available types in C #_ Unavailable type_ C double question mark_ C question mark point_ C null is not equal to
Using linked list to find set union
Sword finger offer2: queue summary