在QTableView、QTreeView以及对于衍生的QTableWidget、QTreeWidget类中,需要用到自定义委托的情形很多,比如提供下拉框选择,进度条展示下载进度啥的,默认的单元格是没有这些效果的,需要自己单独用委托的形式来展示,自定义委托一般有两种UI形式,一种是单元格一直显示对应的委托控件比如复选框、按钮、进度条等,一种是用户鼠标按下才显示对应的委托控件,鼠标离开自动恢复原有单元格的形式。
在设计这个委托类的时候,综合考虑了很多应用场景需求,例如复选框、文本框、下拉框、日期框、微调框、进度条等都支持,而且就合并在一个类中,方便直接new使用,通过函数指定不同的委托类型即可,也经过大量的项目实战应用,逐步完善到现在的程度。
自定义委托全家桶特点:
自定义委托全家桶应用场景:
关于Qt数据库相关开发的一些经验总结:
https://qtchina.blog.csdn.net/article/details/119022424
#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();
}
}