1.首先需要使用Qt创建一个Qt GUI应用.
2.基类选择QWidget.
3.自动生成好的工程目录如下,而kqdicwidget.ui文件和相应的.cpp和.h文件是我后来添加的按钮弹出窗口文件.
4.设计好UI界面,对象名如下.
4.如下就是dicwidget.cpp文件的代码.
dicwidget.h文件如下.
#ifndef DICWIDGET_H
#define DICWIDGET_H
#include
#include
#include
namespace Ui {
class DicWidget;
}
class DicWidget : public QWidget
{
Q_OBJECT
public:
explicit DicWidget(QWidget *parent = 0);
~DicWidget();
private:
Ui::DicWidget *ui;
public slots:
void curIndex(); //combobox的信号与槽函数
private slots:
void on_AddBtn_clicked();
void on_UpdataBtn_clicked();
void on_DelBtn_clicked();
void on_ExitBtn_clicked();
void on_SaveBtn_clicked();
private:
void InitCombo(); //初始化Combobox
void ConnectDataBase(); //连接数据库
void LoadTree(); //刷新树列表
void reftree(QStandardItem*); //递归遍历树
void reftreechild(QStandardItem*,int&); //递归遍历子项
private:
QStandardItemModel *model; //标准项目模型
public:
QStandardItem *currentItem;
public:
QMap NameTypeMap; //QMap方便数据的映射
QString addName;
QStringList listname;
QList listslid;
QList listdlid;
QStringList header;
QString dicname;
QString name;
QString type;
int refslid; //定义全局变量
int refdlid;
};
#endif // DICWIDGET_H
dicwidget.cpp文件如下.
#include "dicwidget.h"
#include "ui_dicwidget.h"
#include
#include
#include
#include
#include "kqdatedicwidget.h"
#include
#include
#include
#include
#pragma execution_character_set("utf-8")
DicWidget::DicWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::DicWidget)
{
ui->setupUi(this);
this->setFixedSize(540,300);
//初始化combobox控件
InitCombo();
connect(ui->comboBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(curIndex()));
//设置窗口的属性
this->setWindowFlags(Qt::WindowCloseButtonHint|Qt::MSWindowsFixedSizeDialogHint);
ui->treeView->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置TreeView为不可编辑
}
DicWidget::~DicWidget()
{
delete ui;
}
void DicWidget::InitCombo() //初始化combobox
{
ConnectDataBase(); //连接本地数据库方法
QSqlQuery query;
query.exec("select * from ATT_DIC_TREE where SJID = 0 order by type");
while(query.next())
{
QString map_name = query.value(0).toString(); //获取数据库字段值
QString map_type = query.value(1).toString();
NameTypeMap[map_name] = map_type; //使用QMap映射值
ui->comboBox->addItem(map_name); //设置值到combobox上
}
}
void DicWidget::curIndex() //combobox的点击后执行的槽方法
{
ConnectDataBase();
QSqlQuery query;
QString rSql = QString("SELECT * FROM ATT_DIC_TREE where TYPE = '%1' and sjid = 0").arg(NameTypeMap[ui->comboBox->currentText()]); //使用映射获取数据库的type
query.exec(rSql);
header.clear(); //QStringList的header的变量
while(query.next())
{
QString r_name = query.value(4).toString();
dicname = query.value(4).toString();
header << r_name; //获取的值存入header中
}
model = new QStandardItemModel(ui->treeView);
//model->setHorizontalHeaderLabels(QStringList()<setHorizontalHeaderLabels(header); //设置TreeView的头标题
listname.clear(); //清空List数据
listslid.clear();
listdlid.clear();
LoadTree();
}
void DicWidget::LoadTree() //加载树控件
{
QSqlQuery query;
QString dtype = NameTypeMap[ui->comboBox->currentText()]; //映射出type
// int i = ui->comboBox->currentIndex();
// QString dtype = QString::number(i+1,10);
QString sql = QString("SELECT * FROM ATT_DIC_TREE where TYPE = '%1' order by SJID,DLID;").arg(dtype);
query.exec(sql);
//如下开始从QMap中的数据加载到树控件上
while(query.next())
{
QMap mMapItems;
while(query.next())
{
int dlid = query.value(2).toInt();
int sjid = query.value(3).toInt();
QString name = query.value(4).toString();
if(sjid==0 || mMapItems.constFind(sjid)==mMapItems.constEnd())
{
QStandardItem *itemProject2 = new QStandardItem(name);
itemProject2->setData(name);
model->appendRow(itemProject2);
mMapItems[dlid]=itemProject2;
}
else if(mMapItems.constFind(sjid)!=mMapItems.constEnd())
{
QStandardItem* pPar=mMapItems[sjid];
QStandardItem* item0 = new QStandardItem(name);
item0->setData(name);
pPar->appendRow(item0);
mMapItems[dlid]=item0;
}
if(name.isEmpty())
break;
}
break;
}
QString NameTypeSql = QString("SELECT * FROM ATT_DIC_TREE where type = '%1' and sjid = 0").arg(dtype);
query.exec(NameTypeSql);
while(query.next())
name = query.value(0).toString();
ui->treeView->setModel(model);
}
void DicWidget::ConnectDataBase() //与本地mdb数据库的连接
{
QString sDbNm ="C:/Users/Administrator/Desktop/SysDic.mdb"; //路径可修改
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
QString dsn = QString("DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};FIL={MS Access};DBQ=%1;").arg(sDbNm);
db.setDatabaseName(dsn);
db.setUserName("");
db.setPassword("");
bool ok = db.open();
if(!ok)
{
QMessageBox messagebox;
messagebox.setText("Database error");
messagebox.exec();
db.close();
}
}
void DicWidget::on_AddBtn_clicked() //添加按钮的方法
{
QStandardItemModel *model1 = static_cast(ui->treeView->model());
QModelIndex currentindex = ui->treeView->currentIndex();
if(currentindex.row()==-1) //如果未选中树节点的一项则return
return;
currentItem = model1->itemFromIndex(currentindex);
kqDateDicWidget dlg; //点击按钮后弹出一个窗口进行数据的添加
dlg.setTitle("add"); //次窗口的ui是kqdatadicwidget.ui相应的.cpp和.h文件见项目目录
dlg.setModal(true);
dlg.exec();
QString additem = dlg.GetValues(); //获取弹出窗口输入的值
if(!additem.isEmpty())
{
QStandardItem *itemChild = new QStandardItem(additem);
currentItem->appendRow(itemChild);
ui->treeView->setExpanded(currentindex,true); //每添加一项则展开当前子项
}
// ConnectDataBase();
// QSqlQuery query;
// QString sql = QString("SELECT * FROM ATT_DIC_TREE where DICNAME = '%1' order by SJID,DLID;").arg(currentItem->text());
// query.exec(sql);
// while(query.next())
// {
// addDlid = query.value(2).toInt();
// addName = query.value(0).toString();
// }
// int i = ui->comboBox->currentIndex();
// QString dtype = QString::number(i+1,10);
// QString maxDlidSql = QString("SELECT max(DLID) FROM ATT_DIC_TREE where type = '%1'").arg(dtype);
// query.exec(maxDlidSql);
// while(query.next())
// maxDlid = query.value(0).toInt();
}
void DicWidget::on_UpdataBtn_clicked() //修改按钮的方法
{
QStandardItemModel *model1 = static_cast(ui->treeView->model());
QModelIndex currentindex = ui->treeView->currentIndex();
if(currentindex.row()==-1)
return;
currentItem = model1->itemFromIndex(currentindex);
kqDateDicWidget dlg;
dlg.setTitle("update");
dlg.setModal(true);
dlg.exec();
QString additem = dlg.GetValues();
if(!additem.isEmpty())
{
//QStandardItem *itemChild = new QStandardItem(additem);
currentItem->setText(additem); //实现修改树节点的文本
}
}
void DicWidget::on_DelBtn_clicked() //删除树节点的方法
{
QStandardItemModel *model1 = static_cast(ui->treeView->model());
QModelIndex currentindex = ui->treeView->currentIndex();
if(currentindex.row()==-1) //如果没有选中树节点则提示需要选中节点
{
int war = QMessageBox::warning(NULL,"warning","Please select a deletion item !",QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
if(war == QMessageBox::Yes || war == QMessageBox::No)
return;
}
int rb = QMessageBox::warning(NULL,"warning","Are you sure to delete !",QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
if(rb == QMessageBox::Yes)
{
currentItem = model1->itemFromIndex(currentindex);
if(!currentItem->parent())
{
model1->removeRow(currentindex.row());
//currentItem->removeRows(0,currentItem->rowCount());
//delete currentItem->takeRow(currentindex.row());
return;
}
QStandardItem *parent = currentItem->parent();
parent->removeRow(currentindex.row()); //删除树节点
//delete parent->takeChild(currentindex.row());
}
}
void DicWidget::reftree(QStandardItem* item) //递归遍历树的方法开始
{
if(item==nullptr)
return;
QString itemname = item->text(); //获取树的一层节点的数据
listname.append(itemname);
listslid.append(refslid);
listdlid.append(refdlid);
reftreechild(item,refdlid); //开始遍历树节点的子项节点
}
void DicWidget::reftreechild(QStandardItem* model,int& dlid) //递归子项的方法
{
int nSJID=dlid;
for(int i=0;irowCount();i++)
{
QStandardItem* childitem2 = model->child(i);
dlid++;
QString childtext = childitem2->text(); //设置下一个节点
listname.append(childtext);
listslid.append(nSJID);
listdlid.append(dlid);
reftreechild(childitem2,dlid); //递归
}
}
void DicWidget::on_SaveBtn_clicked() //保存按钮的方法
{
refslid = 1; //通过数据库的规则从根节点的下一个节点开始遍历(设置初始值)
refdlid = 2; //自身id为2的开始设置
for(int i =0;irowCount();i++)
{
QStandardItem* childItem = model->item(i,0);
reftree(childItem); //调用遍历树的方法
refdlid++; //除去根节点的下一级节点的id自加
}
ConnectDataBase();
QSqlQuery query;
// int i = ui->comboBox->currentIndex();
// QString dtype = QString::number(i+1,10);
QString dtype = NameTypeMap[ui->comboBox->currentText()];
//先删除当前选中的combobox的数据
QString delSql = QString("delete from ATT_DIC_TREE where type = '%1'").arg(dtype);
query.exec(delSql);
//开始保存入库,将根节点的数据保存如数据库中
QString root_str = dicname;
QString firstSql = QString("insert into ATT_DIC_TREE (NAME,TYPE,DLID,SJID,DICNAME,DICCODE) values ('%1','%2',%3,%4,'%5','%6')").arg(name).arg(dtype).arg(1).arg(0).arg(root_str).arg(123);
query.exec(firstSql);
//开始将所有节点(除去根节点)保存入数据库中
for(int n=0;nclose();
}
5.如下就是点击按钮后弹出一个窗口,用来修改数据的ui文件和.cpp文件还有.h文件.
kqdatedicwidget.ui文件的设计如下.
kqdatedicwidget.h文件代码如下.
#ifndef KQDATEDICWIDGET_H
#define KQDATEDICWIDGET_H
#include
namespace Ui {
class kqDateDicWidget;
}
class kqDateDicWidget : public QDialog
{
Q_OBJECT
public:
explicit kqDateDicWidget(QWidget *parent = 0);
~kqDateDicWidget();
private slots:
void on_pushButton_2_clicked();
void on_okBtn_clicked();
private:
Ui::kqDateDicWidget *ui;
public:
QString addname;
public:
QString GetValues();
void setTitle(QString);
signals:
void dlgReturn(QString);
};
#endif // KQDATEDICWIDGET_H
kqdatedicwidget.cpp文件代码如下.
#include "kqdatedicwidget.h"
#include "ui_kqdatedicwidget.h"
#include
kqDateDicWidget::kqDateDicWidget(QWidget *parent) :
QDialog(parent),
ui(new Ui::kqDateDicWidget)
{
this->setMinimumSize(200,120);
this->setMaximumSize(200,120);
//设置窗口的属性
this->setWindowFlags(Qt::WindowCloseButtonHint|Qt::MSWindowsFixedSizeDialogHint);
ui->setupUi(this);
}
kqDateDicWidget::~kqDateDicWidget()
{
delete ui;
}
void kqDateDicWidget::on_pushButton_2_clicked() //取消按钮的方法
{
this->close();
}
void kqDateDicWidget::on_okBtn_clicked() //确定按钮的方法
{
addname = ui->lineEdit->text(); //获取文本框的值
if(addname.isEmpty())
{
QMessageBox::information(NULL,"Tip","Please enter text !",QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
return;
}
this->close();
}
QString kqDateDicWidget::GetValues()
{
return addname; //返回文本框的值
}
void kqDateDicWidget::setTitle(QString type) //根据点击的按钮的不同来设置窗口的标题
{
if(type == "add")
this->setWindowTitle("Add Fileds");
else if(type == "update")
this->setWindowTitle("Update Fileds");
else if(type == "delete")
this->setWindowTitle("Delete Files");
}
6.下面就是main.cpp的文件了main.cpp文件没有什么修改的.
#include "dicwidget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DicWidget w;
w.setWindowTitle("QtTreeView的设置");
w.show();
return a.exec();
}
7.实现的效果图片.
未修改treeview节点的原数据图如下.
然后我在棒球节点下添加一个 "陈棒球" 节点,我再修改自行车节点为 "大雄的自行车",最后删除胖虎节点,最后点击保存.
下面是修改win10的树控件的风格为win7的风格,让TreeView控件有连接线
#include
构造函数里面
{
ui->setupUi(this);
......
ui->treeView->setStyle(QStyleFactory::create("windows"));//让行政区树有连接线
}
效果如下:
需要下载该小工具项目的源码和该项目的mdb数据库的请点击链接: : https://download.csdn.net/download/superman___007/10983400
或者在百度云链接: https://pan.baidu.com/s/1bxI31qrknLi4Ci-nkR5ycQ 提取码: 98hr