赞
踩
因工作需要,要实现一个小型的数据管理系统。本着想捡起来QT技能的想法,学习下QT下管理系统设计。
首先肯定是设计界面按照想要的方式进行展示,使用sqlite对数据进行管理,数据excel格式的导入导出,界面的搜索功能,条件选择功能,单条数据的编辑更改功能,账户管理功能。
根据不同模块进行分类设计
数据仓库类
对于数据源的管理设计DBFactory类对数据库操作进行封装,提供数据库连接,创建表,select等操作
数据模型类
模型本身不存储数据,仅提供接口供视图使用,QT提供的QsqlTableModel已经够用
单条数据的编辑可用QDataWidgetMaper类进行数据映射。
数据视图类
提供视图用来展示数据,和搜索功能
数据I/O类
提供excel文件的导入导出功能
登录管理类
提供登录功能及账户管理功能
定义了创建数据库连接和创建表的函数。
#ifndef DBFACTORY_H #define DBFACTORY_H #include <QtSql> #include <QSqlDatabase> class DBFactory { public: DBFactory(); QSqlError createConnection(); QSqlError createUserTable(const QSqlDatabase &DataBase); QSqlError createTable(const QSqlDatabase &DataBase); void addUser(QSqlQuery &q, const QString &name, const QString &password,const QString &phoneNumber,const QString &role); void addProvince(QSqlQuery &q, const QString &province, const QString &area); QSqlDatabase DataBase() const; void setDataBase(const QSqlDatabase &DataBase); QStringList getContentFromDataBase(const QString &tableName, const int column); private: QSqlDatabase m_DataBase; }; #endif // DBFACTORY_H
具体实现可以参考QT帮助文档关于SQL的页面。
提供一个对话框供用户输入用户名和密码。
在main函数中,首先构造登录对话框,在登录对话框构造函数中,建立数据库连接,并初始化用户表,如有,则直接跳过。
LoginDialog::LoginDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::LoginDialog)
{
//建立数据库连接
m_pDBFactory = new DBFactory();
QSqlError err = m_pDBFactory->createConnection();
if(err.type() != QSqlError::NoError)
{
QMessageBox::critical(this,tr("错误"),tr("数据库连接错误,请稍后重试!")+ err.text(),QMessageBox::Ok);
// return;
}
m_pDBFactory->createUserTable(m_pDBFactory->DataBase());
ui->setupUi(this);
}
用户输入完成后点击界面登录按钮触发相应槽函数,在对应槽函数中,检索数据库用户表,匹配密码是否正确。如正确则发出accept信号,主函数接受到后,关闭登录界面,打开主显示界面。
if(checkUserPassword(ui->UserNameEdit->text(),ui->PassWordEdit->text())) {QDialog::accept();} bool LoginDialog::checkUserPassword(QString name,QString passward) { QSqlQuery checkquery; QString str = QString("select * from user where UName = '%1' and UPassward = '%2'").arg(name).arg(passward); checkquery.exec(str); //返回最后一条符合记录的位置, checkquery.last(); int record = checkquery.at() + 1; if(record == 0) { return false; } loginRole = checkquery.value(3).toString(); qDebug()<<loginRole; return true; }
在checkuserPassword函数中检索数据库,并根据不同的用户名分配不同的权限,传递给主界面构造函数用于限制部分功能。
主界面用于管理视图和模型,提供一个构造函数,和相应的菜单及其槽函数。在构造函数中进行相应视图的创建。并根据传入角色分配不同的菜单。
MainWindow::MainWindow(const QString &role, QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建数据表格,导入数据
m_pDBFactory = new DBFactory();
m_pDBFactory->createCustomerTable(m_pDBFactory->DataBase());
//先构建视图
m_pViewManager = new ViewManager();
setCentralWidget(m_pViewManager->pTabWidget());
//获取视图对应的模型
m_pModel=m_pViewManager->pCustomerManager()->getCustomerModel();
CreateMenu(role);
}
为方便拓展,先建立一个视图管理类添加一个tabwidget控件,再结合不同模型建立对应视图类,将视图作为tab页添加到视图管理类的tab控件中。
使用QTableView控件作为视图进行数据展示。使用该控件提供的函数进行一些基本的增删改查函数编写。
默认该视图是可编辑的,故提供了一个函数用来导入模型并设置标签。并在视图构造函数中调用并将模型设置给视图。
bool CustomerManager::setModel() { //关联数据模型 customerModel = new QSqlTableModel(ui->tableView); customerModel->setEditStrategy(QSqlTableModel::OnManualSubmit); customerModel->setTable("Customers"); //添加表头 customerModel->setHeaderData(0,Qt::Horizontal, tr("ID")); customerModel->setHeaderData(1,Qt::Horizontal, tr("客户地址")); // Populate the model: if(!customerModel->select()) { return false; } return true; }
setModel();
ui->tableView->setModel(customerModel);
//列宽随窗口大小改变而改变,每列平均分配,充满整个表,但是此时列宽不能拖动进行改变
ui->tableView->resizeColumnsToContents();
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui->tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
上边的步骤完成后,就可以将数据库中的数据显示在界面上了。接下来就是实现增删改查的功能。
单行新增
通过按钮槽函数,打开新的对话框表单,填写后将表单获取的数据组合成需要的SQL语句并提交,在槽函数中更新视图。
void CustomerManager::on_addButton_clicked()
{
AddCustomerDialog *dialog = new AddCustomerDialog(customerModel,this);
int accepted = dialog->exec();
if (accepted == 1)
{
int lastRow = customerModel->rowCount() - 1;
ui->tableView->selectRow(lastRow);
ui->tableView->scrollToBottom();
}
}
单行删除
删除选中记录,因视图设置为单行选中,所以仅实现单行删除功能。
void CustomerManager::delCustomer() { QModelIndexList selection = ui->tableView->selectionModel()->selectedRows(0); if(!selection.empty()) { QModelIndex idIndex = selection.at(0); QMessageBox::StandardButton button; button = QMessageBox::question(this,tr("删除确认"),QString(tr("确认删除此条客户信息吗?")),QMessageBox::Yes|QMessageBox::No); if(button == QMessageBox::Yes){ removeCustomerFromDatabase(idIndex); }else{ QMessageBox::information(this, tr("删除客户"),tr("请选择要删除的客户信息。")); } } } void CustomerManager::removeCustomerFromDatabase(QModelIndex index) { customerModel->removeRow(index.row()); customerModel->submit(); }
条件搜索
条件选择搜索功能实现,依据下拉框选项组合where条件选择语句,设置customermodel的过滤器filter。
如
void CustomerManager::on_AreaSelectBox_currentIndexChanged(const QString &arg1) { //更新省区选择项 QSqlQueryModel *provinceselectModel = new QSqlQueryModel(this); QString provinceSelectstr = QString("select DISTINCT province from Provinces where area = '%1'").arg(arg1); provinceselectModel->setQuery(provinceSelectstr); ui->ProvinceSelectBox->setModel(provinceselectModel); if(arg1 != "请选择归属大区"){ //构建过滤器即where条件语句 QString filter; filter.append(QString("CArea = '%1'").arg(arg1)); if(ui->ProvinceSelectBox->currentText()!= "请选择归属省份") { filter.append(QString(" and ")); filter.append(QString("CProvince = '%1'").arg(ui->ProvinceSelectBox->currentText())); } if(ui->ProduceTypeBox->currentText()!="请选择企业性质") { filter.append(QString(" and ")); filter.append(QString("CProduceType = '%1'").arg(ui->ProduceTypeBox->currentText())); } if(ui->CustomerTypeBox->currentText()!="请选择客户类型") { filter.append(QString(" and ")); filter.append(QString("CCustomerType = '%1'").arg(ui->CustomerTypeBox->currentText())); } qDebug()<<filter; customerModel->setFilter(filter); ui->ProvinceSelectBox->setEnabled(true); }else { //重置所有下拉框并显示所有数据 ui->ProvinceSelectBox->setCurrentIndex(0); ui->ProvinceSelectBox->setEnabled(false); ui->ProduceTypeBox->setCurrentIndex(0); ui->CustomerTypeBox->setCurrentIndex(0); customerModel->setFilter(QString("")); customerModel->select(); } }
文字搜索
文字搜索功能实现,依据输入文本对视图数据项进行检索
void CustomerManager::on_SearchButton_clicked() { QString searchText = ui->SearchEdit->text(); if(searchText=="") { for(int i=0;i<ui->tableView->model()->rowCount();i++) ui->tableView->setRowHidden(i,false); } else { //获取文本框内容 searchText.remove(QRegExp("\\s")); for(int i=0;i<ui->tableView->model()->rowCount();i++) { ui->tableView->setRowHidden(i,true); QString r=""; //提取客户信息 QAbstractItemModel *model=ui->tableView->model(); QModelIndex index; for(int j=0;j<ui->tableView->model()->columnCount();j++) { index=model->index(i,j); r+=model->data(index).toString(); } r.remove(QRegExp("\\s")); if(r.contains(searchText,Qt::CaseSensitive)) ui->tableView->setRowHidden(i,false); } } }
后期还需实现图片显示,数据量大时分页显示,可通过子类化QSQLTableModel来实现。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。