这些日子在做一个数据库管理系统,其中有这么一个小需求:点击按钮,读取数据库中的公司部门表,用树形结构显示各个部门的关系。如下图:
左边为Sqlserver的一张表,列出了部门ID (DEPART_ID),部门名称 (DEPART_NAME),上级部门ID (DEPART_UPPER_DEPT)
右图为点击按钮后弹出一窗口,里面显示了表中各部门的包含关系。
1 Qt连接数据库,不会的参考这篇博文:基于Qt+海康sdk+MySql的远程录像下载程序
2 设计师界面创建好 TreeWidget 并设置好布局。
3 通过Sql语句查询表的最高层部门(即 DEPART_UPPER_DEPT 为空) 的部门。[ Demo表中为股东和总经理 ]
4 获得最高层部门的信息,创建 QTreeWidgetItem 放入 TreeWidget作为根节点。
5 开始循环。传入部门名称,Sql语句查询下级,若有下级,则为下级创建新的 QTreeWidgetItem 并放入当前部门的 item 中。递归,继续查询下级的下级。若没有下级,则返回。
1.创建界面:找到TreeWidget拖进去就行,很简单。
根据需求设置界面的布局。我定义了一个类,在类的初始化中进行布局。
this->resize(300,600); //设置窗口大小
setFixedSize(this->width(), this->height()); //固定窗口,不可伸缩
ui->treeWidget->setGeometry(5,5,290,590); //设置TreeWidget位置,和窗口匹配
2. QtreeView初始化,设置表头
void Tree::Tree_Init()
{
ui->treeWidget->clear(); //清空内容
ui->treeWidget->headerItem()->setText(0,"部门名称"); //设置字段,部门名称
departTree("",ui->treeWidget); //开始第一次插入
}
第一次插入,传入参数为("",ui->treeWidget)。由于我的表中最高级部门的上级为空,所以第一次传入""。不能传NULL,否则无法查询出结果。
departTree 函数,查询和递归在这两个函数内完成。需要穿两种不同类型参数,用到了函数重载。
void departTree(QString root, QTreeWidgetItem *item); //后续递归调用,插入到父亲节点
void departTree(QString root,QTreeWidget *tree); //第一次插入,根节点,最高级部门
void Tree::departTree(QString root,QTreeWidgetItem *item)
{
QSqlQuery query(sql.db);
query.exec("select DEPART_NAME,DEPART_ID from TAB_DEPART where DEPART_UPPER_DEPT='"+root+"'"); //设置查询语句
while (query.next())
{
QString DEPART_NAME = query.value(0).toString(); //获取部门名称
QString DEPART_ID = query.value(1).toString(); //获取部门ID
QTreeWidgetItem *items =
new QTreeWidgetItem(item,QStringList(QString(DEPART_NAME)));
/*创建新的ITEM,插入到ITEM中,设置名称为当前查询到的部门名称*/
if(!DEPART_NAME.isEmpty())
{
departTree(DEPART_ID,items); //递归,若传入查询到的部门,判断是否还有下级
}
}
return;
}
void Tree::departTree(QString root, QTreeWidget *tree)
{
QSqlQuery query(sql.db);
query.exec("select DEPART_NAME,DEPART_ID from TAB_DEPART where DEPART_UPPER_DEPT='"+root+"'");
while (query.next())
{
QString DEPART_NAME = query.value(0).toString();
QString DEPART_ID = query.value(1).toString();
QTreeWidgetItem *item =
new QTreeWidgetItem(tree,QStringList(QString(DEPART_NAME)));
/*创建ITEM,由于是最高部门,插入对象为TreeWidget*/
if(!DEPART_NAME.isEmpty())
{
departTree(DEPART_ID,item); //开启递归
}
}
return;
}
设置一个按钮,调用Tree_Init()函数,就能显示出目录。别忘了this->show();