Qt数据库应用之超级自定义委托

 更新时间:2022年03月11日 08:40:02   作者:feiyangqingyun  
Qt中需要用到自定义委托的情形很多,比如提供下拉框选择,进度条展示下载进度啥的,默认的单元格是没有这些效果的,需要自己单独用委托的形式来展示。本文将为大家介绍Qt中如何进行超级自定义委托,需要的可以参考一下

一、前言

在QTableView、QTreeView以及对于衍生的QTableWidget、QTreeWidget类中,需要用到自定义委托的情形很多,比如提供下拉框选择,进度条展示下载进度啥的,默认的单元格是没有这些效果的,需要自己单独用委托的形式来展示,自定义委托一般有两种UI形式,一种是单元格一直显示对应的委托控件比如复选框、按钮、进度条等,一种是用户鼠标按下才显示对应的委托控件,鼠标离开自动恢复原有单元格的形式。

在设计这个委托类的时候,综合考虑了很多应用场景需求,例如复选框、文本框、下拉框、日期框、微调框、进度条等都支持,而且就合并在一个类中,方便直接new使用,通过函数指定不同的委托类型即可,也经过大量的项目实战应用,逐步完善到现在的程度。

自定义委托全家桶特点:

  1. 可设置多种委托类型,例如复选框、文本框、下拉框、日期框、微调框、进度条等。
  2. 可设置是否密文显示,一般用于文本框。
  3. 可设置是否允许编辑,一般用于下拉框。
  4. 可设置是否禁用,一般用来禁用某列。
  5. 可设置数据集合,比如下拉框数据集合。
  6. 提供值变化信号,比方说下拉框值改动触发。
  7. 可设置数据校验自动产生不同的图标。
  8. 支持设置校验列、校验规则、校验值、校验成功图标、校验失败图标、图标大小。
  9. 可设置校验数据产生不同的背景颜色和文字颜色。
  10. 校验规则支持 == > >= < <= != contains,非常丰富。
  11. 复选框自动居中而不是左侧,切换选中状态发送对应的信号。
  12. 可设置颜色委托,自动根据颜色值绘制背景颜色,自动设置最佳文本颜色。
  13. 可设置按钮委托,自动根据值生成多个按钮,按钮按下发送对应的信号。
  14. 当设置了委托列时自动绘制选中背景色和文字颜色。
  15. 可设置关键字对照表绘制关键字比如原始数据是 0-禁用 1-启用。
  16. 可设置复选框对应的映射选中不选中关键字。
  17. 根据不同的委托类型绘制,可以依葫芦画瓢自行增加自己的委托。
  18. 所有功能封装成1个类,核心代码不到500行,使用极其方便友好。

自定义委托全家桶应用场景:

  1. 某个字段需要提供下拉框进行选择,下拉框可选是否允许编辑。
  2. 某个字段需要提供密码框进行输入,密文显示字段值。
  3. 某个字段需要提供日期框下拉选择日期时间。
  4. 某个字段需要提供微调框设定值。
  5. 某个字段需要提供进度条显示字段值。
  6. 某个字段列需要禁用。
  7. 各种委托控件可以设置初始的数据集合,比如下拉框。
  8. 各种委托控件在值发生变化的时候发出valuechanged信号,比如下拉框选择声音文件的时候进行播放试听,微调框值改变的时候联动其他控件进行处理等。
  9. 某个字段根据设定的规则进行数据校验自动产生不同的图标显示,比如报警红色图标/正常绿色图标,一目了然。同时可设置校验列/校验规则/校验值/校验成功图标/校验失败图标/图标大小。
  10. 某个字段根据设定的规则进行数据校验自动绘制不同的背景颜色醒目显示,可设定规则包括 == > >= < <= != contains,可设置符合要求的内容文字颜色/背景颜色。
  11. 某个字段需要根据内容显示复选框(自动居中),比如内容是 0/禁用/false 等复选框不选中,1/启用/true 等复选框选中,具体选中不选中对应的内容可自定义。
  12. 某个字段需要根据内容重新替换显示成自定义的内容,比如值是0而需要显示成“不符合”字样,1显示成“符合”字样。对应的内容替换规则可设置关键字对照表。
  13. 某个字段需要根据颜色值显示对应的颜色,同时可以单击选中进行颜色选择。
  14. 某列需要显示操作按钮,按钮的个数/文字集合可设定,根据设定的文字集合平分宽度绘制按钮,单击某个按钮发送对应的按钮单击信号,带按钮索引以及行列,用于用户自行处理。
  15. 一个类通用所有需要委托的场景,相当于一个轮子用在所有项目中,不需要单独再去写不同的委托类。
  16. 一个类通用所有支持委托的控件,比如QTableView/QTableWidget/QListView/QTreeWidget/QListWidget等。

Qt数据库相关应用开发总结

二、功能特点

  1. 同时支持多种数据库比如odbc、sqlite、mysql、postgresql、sqlserver、oracle、人大金仓等。
  2. 一个数据库类即可管理本地数据库通信,也支持远程数据库通信等。
  3. 数据库线程支持执行各种sql语句,包括单条和批量。
  4. 组件中的所有类打印信息、错误信息、执行结果都信号发出去。
  5. 集成数据库通用翻页类(负责具体处理逻辑),搭配分页导航控件(负责外观),形成超级牛逼的翻页控件。
  6. 集成数据库自动清理类,设定最大记录数后台自动清理早期数据。
  7. 集成自定义委托类,支持复选框、文本框、下拉框、日期框、微调框、进度条等。
  8. 同时支持Qt4-Qt6,亲测Qt4.6到Qt6.3任意版本,任意系统和编译器。
  9. 本组件无故障 360天7乘24小时 运行在至少上万个现场,商业级别品质保证。
  10. 每个类都对应完整详细的使用示例,注释详细,非常适合阅读学习。
  11. 可以作为独立的程序运行,比如自动清理早期数据,同步数据到云端。
  12. 全部线程处理,不卡界面,自动重连数据库。
  13. 普通测试情况,sqlite数据库,数据库发生器每秒钟插入1000条记录约0.003秒钟,同时自动清理数据类每秒钟删除1000条记录约0.13秒,不同线程互不干扰。

三、体验地址

体验地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg  提取码:uyes 文件名:bin_dbtool.zip

国内站点:https://gitee.com/feiyangqingyun

国际站点:https://github.com/feiyangqingyun

四、效果图

五、相关代码

#include "frmdbdelegate.h"
#include "ui_frmdbdelegate.h"
#include "quihelper.h"
#include "dbdelegate.h"
#include "dbconnthread.h"

frmDbDelegate::frmDbDelegate(QWidget *parent) : QWidget(parent), ui(new Ui::frmDbDelegate)
{
    ui->setupUi(this);
    this->initForm();
}

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

void frmDbDelegate::showEvent(QShowEvent *)
{
    static bool isShow = false;
    if (!isShow) {
        isShow = true;
        QTimer::singleShot(100, this, SLOT(initDb()));
        QTimer::singleShot(500, this, SLOT(initData()));
    }
}

void frmDbDelegate::initForm()
{
    QUIHelper::initTableView(ui->tableView, 25, false, true);

    //实例化数据库通信类
    dbConn = new DbConnThread(this);
    dbConn->setDbFlag("委托");
    connect(dbConn, SIGNAL(debug(QString)), this, SLOT(debug(QString)));
    connect(dbConn, SIGNAL(error(QString)), this, SLOT(error(QString)));
}

void frmDbDelegate::initDb()
{
    DbInfo dbInfo;
    //强制本程序带的数据库 dbtool.db
    dbInfo.dbName = DbHelper::getDbDefaultFile();
    dbConn->setConnInfo(DbHelper::getDbType("sqlite"), dbInfo);
    if (!dbConn->openDb()) {
        QUIHelper::showMessageBoxError("委托数据库打开失败!");
    }
}

void frmDbDelegate::initData()
{
    if (!dbConn->getOk()) {
        return;
    }

    model = new QSqlTableModel(this);
    model->setTable("UserInfo");
    model->setSort(0, Qt::AscendingOrder);
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();

    ui->tableView->setModel(model);
    ui->tableView->setProperty("model", true);

    QList<QString> columnNames;
    columnNames << "用户名称" << "用户密码" << "用户类型" << "模块A" << "模块B" << "模块C" << "模块D" << "模块E" << "模块F" << "模块G" << "备注";
    QList<int> columnWidths;
    columnWidths << 100 << 120 << 80 << 60 << 60 << 60 << 60 << 60 << 60 << 60 << 60;

    int count = columnNames.count();
    for (int i = 0; i < count; i++) {
        model->setHeaderData(i, Qt::Horizontal, columnNames.at(i));
        ui->tableView->setColumnWidth(i, columnWidths.at(i));
    }

    //用户密码委托
    DbDelegate *d_txt_userPwd = new DbDelegate(this);
    d_txt_userPwd->setDelegateType("QLineEdit");
    d_txt_userPwd->setDelegatePwd(true);
    d_txt_userPwd->setDelegateColumn(1);
    ui->tableView->setItemDelegateForColumn(1, d_txt_userPwd);

    //用户类型委托
    QStringList userType;
    userType << "操作员" << "管理员";
    DbDelegate *d_cbox_userType = new DbDelegate(this);
    d_cbox_userType->setDelegateType("QComboBox");
    d_cbox_userType->setDelegateValue(userType);
    ui->tableView->setItemDelegateForColumn(2, d_cbox_userType);

    //启用禁用委托
    for (int i = 3; i < (3 + 7); i++) {
        DbDelegate *d_ckbox_userAdmin = new DbDelegate(this);
        d_ckbox_userAdmin->setDelegateColumn(i);
        d_ckbox_userAdmin->setDelegateType("QCheckBox");
        d_ckbox_userAdmin->setCheckBoxText("启用", "禁用");
        ui->tableView->setItemDelegateForColumn(i, d_ckbox_userAdmin);
    }
}

void frmDbDelegate::debug(const QString &msg)
{

}

void frmDbDelegate::error(const QString &msg)
{

}

void frmDbDelegate::on_btnAdd_clicked()
{
    int count = model->rowCount();
    model->insertRow(count);

    QString userName = model->index(count - 1, 0).data().toString();
    QString userPwd = model->index(count - 1, 1).data().toString();
    QString userType = model->index(count - 1, 2).data().toString();
    QString userAdmin1 = model->index(count - 1, 3).data().toString();
    QString userAdmin2 = model->index(count - 1, 4).data().toString();
    QString userAdmin3 = model->index(count - 1, 5).data().toString();
    QString userAdmin4 = model->index(count - 1, 6).data().toString();
    QString userAdmin5 = model->index(count - 1, 7).data().toString();
    QString userAdmin6 = model->index(count - 1, 8).data().toString();
    QString userAdmin7 = model->index(count - 1, 9).data().toString();
    QString userMark = model->index(count - 1, 10).data().toString();

    //设置新增加的行默认值
    model->setData(model->index(count, 0), userName);
    model->setData(model->index(count, 1), userPwd);
    model->setData(model->index(count, 2), userType);
    model->setData(model->index(count, 3), userAdmin1);
    model->setData(model->index(count, 4), userAdmin2);
    model->setData(model->index(count, 5), userAdmin3);
    model->setData(model->index(count, 6), userAdmin4);
    model->setData(model->index(count, 7), userAdmin5);
    model->setData(model->index(count, 8), userAdmin6);
    model->setData(model->index(count, 9), userAdmin7);
    model->setData(model->index(count, 10), userMark);
    ui->tableView->setCurrentIndex(model->index(count, 0));
}

void frmDbDelegate::on_btnSave_clicked()
{
    model->database().transaction();
    if (model->submitAll()) {
        model->database().commit();
    } else {
        model->database().rollback();
        qDebug() << TIMEMS << model->database().lastError();
        QUIHelper::showMessageBoxError("保存信息失败,请重新填写!");
    }

    //有些数据库需要主动查询一下不然是空白的比如odbc数据源
    model->select();
}

void frmDbDelegate::on_btnDelete_clicked()
{
    int row = ui->tableView->currentIndex().row();
    if (row < 0) {
        QUIHelper::showMessageBoxError("请选择要删除的用户!");
        return;
    }

    if (QUIHelper::showMessageBoxQuestion("确定要删除该用户吗? 删除后不能恢复!") == QMessageBox::Yes) {
        QString userName = model->index(row, 0).data().toString();
        if (userName == "admin") {
            QUIHelper::showMessageBoxError("管理员 [admin] 不能被删除!", 3);
            return;
        }

        model->removeRow(row);
        model->submitAll();
        ui->tableView->setCurrentIndex(model->index(model->rowCount() - 1, 0));
    }
}

void frmDbDelegate::on_btnReturn_clicked()
{
    model->revertAll();
}

void frmDbDelegate::on_btnClear_clicked()
{
    if (model->rowCount() <= 0) {
        return;
    }

    if (QUIHelper::showMessageBoxQuestion("确定要清空所有用户信息吗?") == QMessageBox::Yes) {
        DbHelper::clearTable("UserInfo", AppConfig::LocalDbType);
        model->select();
    }
}

到此这篇关于Qt数据库应用之超级自定义委托的文章就介绍到这了,更多相关Qt自定义委托内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 怎么实现类的成员函数作为回调函数

    怎么实现类的成员函数作为回调函数

    不使用成员函数,为了访问类的成员变量,可以使用友元操作符(friend),在C++中将该函数说明为类的友元即可
    2013-10-10
  • 简单了解C语言中主线程退出对子线程的影响

    简单了解C语言中主线程退出对子线程的影响

    这篇文章主要介绍了简单了解C语言中主线程退出对子线程的影响,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • QT使用QComBox和QLineEdit实现模糊查询功能

    QT使用QComBox和QLineEdit实现模糊查询功能

    模糊查询是指根据用户输入的文本,在下拉框的选项中进行模糊匹配,并动态地显示匹配的选项,本文将使用QComBox和QLineEdit实现模糊查询功能,需要的可以参考下
    2023-11-11
  • C++实现小型图书管理系统

    C++实现小型图书管理系统

    这篇文章主要为大家详细介绍了C++实现小型图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • C语言中printf的两种输出对齐方式

    C语言中printf的两种输出对齐方式

    C语言中左对齐是C语言的默认输出方式,右对齐是一种特殊的输出方式,左对齐和右对齐都对应着一个已知的输出宽度,输出的字符串根据字符串的长度在宽度上进行补充,补充字符是空格,在使用printf函数输出时,需要在格式字符串中使用%-*s和%*s的格式来分别表示
    2024-02-02
  • C++使用string的大数减法运算(2)

    C++使用string的大数减法运算(2)

    这篇文章主要为大家详细介绍了C++使用string的大数减法运算,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • 基于c语言中调试工具的用法汇总(不包含gdb)

    基于c语言中调试工具的用法汇总(不包含gdb)

    本篇文章是对c语言中调试工具的用法进行了汇总,需要的朋友参考下
    2013-05-05
  • C语言基础双指针移除元素解法

    C语言基础双指针移除元素解法

    这篇文章介绍了C语言基础双指针移除元素的解法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • 基于VC编写COM连接点事件的分析介绍

    基于VC编写COM连接点事件的分析介绍

    本篇文章是对VC编写COM连接点事件进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 深入解析C++ STL中的常用容器

    深入解析C++ STL中的常用容器

    这里我们不涉及容器的基本操作之类,只是要讨论一下各个容器其各自的特点。STL中的常用容器包括:顺序性容器(vector、deque、list)、关联容器(map、set)、容器适配器(queue、stac)
    2013-09-09

最新评论