Qt數(shù)據(jù)庫(kù)應(yīng)用之超級(jí)自定義委托
一、前言
在QTableView、QTreeView以及對(duì)于衍生的QTableWidget、QTreeWidget類中,需要用到自定義委托的情形很多,比如提供下拉框選擇,進(jìn)度條展示下載進(jìn)度啥的,默認(rèn)的單元格是沒有這些效果的,需要自己?jiǎn)为?dú)用委托的形式來(lái)展示,自定義委托一般有兩種UI形式,一種是單元格一直顯示對(duì)應(yīng)的委托控件比如復(fù)選框、按鈕、進(jìn)度條等,一種是用戶鼠標(biāo)按下才顯示對(duì)應(yīng)的委托控件,鼠標(biāo)離開自動(dòng)恢復(fù)原有單元格的形式。
在設(shè)計(jì)這個(gè)委托類的時(shí)候,綜合考慮了很多應(yīng)用場(chǎng)景需求,例如復(fù)選框、文本框、下拉框、日期框、微調(diào)框、進(jìn)度條等都支持,而且就合并在一個(gè)類中,方便直接new使用,通過(guò)函數(shù)指定不同的委托類型即可,也經(jīng)過(guò)大量的項(xiàng)目實(shí)戰(zhàn)應(yīng)用,逐步完善到現(xiàn)在的程度。
自定義委托全家桶特點(diǎn):
- 可設(shè)置多種委托類型,例如復(fù)選框、文本框、下拉框、日期框、微調(diào)框、進(jìn)度條等。
- 可設(shè)置是否密文顯示,一般用于文本框。
- 可設(shè)置是否允許編輯,一般用于下拉框。
- 可設(shè)置是否禁用,一般用來(lái)禁用某列。
- 可設(shè)置數(shù)據(jù)集合,比如下拉框數(shù)據(jù)集合。
- 提供值變化信號(hào),比方說(shuō)下拉框值改動(dòng)觸發(fā)。
- 可設(shè)置數(shù)據(jù)校驗(yàn)自動(dòng)產(chǎn)生不同的圖標(biāo)。
- 支持設(shè)置校驗(yàn)列、校驗(yàn)規(guī)則、校驗(yàn)值、校驗(yàn)成功圖標(biāo)、校驗(yàn)失敗圖標(biāo)、圖標(biāo)大小。
- 可設(shè)置校驗(yàn)數(shù)據(jù)產(chǎn)生不同的背景顏色和文字顏色。
- 校驗(yàn)規(guī)則支持 == > >= < <= != contains,非常豐富。
- 復(fù)選框自動(dòng)居中而不是左側(cè),切換選中狀態(tài)發(fā)送對(duì)應(yīng)的信號(hào)。
- 可設(shè)置顏色委托,自動(dòng)根據(jù)顏色值繪制背景顏色,自動(dòng)設(shè)置最佳文本顏色。
- 可設(shè)置按鈕委托,自動(dòng)根據(jù)值生成多個(gè)按鈕,按鈕按下發(fā)送對(duì)應(yīng)的信號(hào)。
- 當(dāng)設(shè)置了委托列時(shí)自動(dòng)繪制選中背景色和文字顏色。
- 可設(shè)置關(guān)鍵字對(duì)照表繪制關(guān)鍵字比如原始數(shù)據(jù)是 0-禁用 1-啟用。
- 可設(shè)置復(fù)選框?qū)?yīng)的映射選中不選中關(guān)鍵字。
- 根據(jù)不同的委托類型繪制,可以依葫蘆畫瓢自行增加自己的委托。
- 所有功能封裝成1個(gè)類,核心代碼不到500行,使用極其方便友好。
自定義委托全家桶應(yīng)用場(chǎng)景:
- 某個(gè)字段需要提供下拉框進(jìn)行選擇,下拉框可選是否允許編輯。
- 某個(gè)字段需要提供密碼框進(jìn)行輸入,密文顯示字段值。
- 某個(gè)字段需要提供日期框下拉選擇日期時(shí)間。
- 某個(gè)字段需要提供微調(diào)框設(shè)定值。
- 某個(gè)字段需要提供進(jìn)度條顯示字段值。
- 某個(gè)字段列需要禁用。
- 各種委托控件可以設(shè)置初始的數(shù)據(jù)集合,比如下拉框。
- 各種委托控件在值發(fā)生變化的時(shí)候發(fā)出valuechanged信號(hào),比如下拉框選擇聲音文件的時(shí)候進(jìn)行播放試聽,微調(diào)框值改變的時(shí)候聯(lián)動(dòng)其他控件進(jìn)行處理等。
- 某個(gè)字段根據(jù)設(shè)定的規(guī)則進(jìn)行數(shù)據(jù)校驗(yàn)自動(dòng)產(chǎn)生不同的圖標(biāo)顯示,比如報(bào)警紅色圖標(biāo)/正常綠色圖標(biāo),一目了然。同時(shí)可設(shè)置校驗(yàn)列/校驗(yàn)規(guī)則/校驗(yàn)值/校驗(yàn)成功圖標(biāo)/校驗(yàn)失敗圖標(biāo)/圖標(biāo)大小。
- 某個(gè)字段根據(jù)設(shè)定的規(guī)則進(jìn)行數(shù)據(jù)校驗(yàn)自動(dòng)繪制不同的背景顏色醒目顯示,可設(shè)定規(guī)則包括 == > >= < <= != contains,可設(shè)置符合要求的內(nèi)容文字顏色/背景顏色。
- 某個(gè)字段需要根據(jù)內(nèi)容顯示復(fù)選框(自動(dòng)居中),比如內(nèi)容是 0/禁用/false 等復(fù)選框不選中,1/啟用/true 等復(fù)選框選中,具體選中不選中對(duì)應(yīng)的內(nèi)容可自定義。
- 某個(gè)字段需要根據(jù)內(nèi)容重新替換顯示成自定義的內(nèi)容,比如值是0而需要顯示成“不符合”字樣,1顯示成“符合”字樣。對(duì)應(yīng)的內(nèi)容替換規(guī)則可設(shè)置關(guān)鍵字對(duì)照表。
- 某個(gè)字段需要根據(jù)顏色值顯示對(duì)應(yīng)的顏色,同時(shí)可以單擊選中進(jìn)行顏色選擇。
- 某列需要顯示操作按鈕,按鈕的個(gè)數(shù)/文字集合可設(shè)定,根據(jù)設(shè)定的文字集合平分寬度繪制按鈕,單擊某個(gè)按鈕發(fā)送對(duì)應(yīng)的按鈕單擊信號(hào),帶按鈕索引以及行列,用于用戶自行處理。
- 一個(gè)類通用所有需要委托的場(chǎng)景,相當(dāng)于一個(gè)輪子用在所有項(xiàng)目中,不需要單獨(dú)再去寫不同的委托類。
- 一個(gè)類通用所有支持委托的控件,比如QTableView/QTableWidget/QListView/QTreeWidget/QListWidget等。
Qt數(shù)據(jù)庫(kù)相關(guān)應(yīng)用開發(fā)總結(jié)
二、功能特點(diǎn)
- 同時(shí)支持多種數(shù)據(jù)庫(kù)比如odbc、sqlite、mysql、postgresql、sqlserver、oracle、人大金倉(cāng)等。
- 一個(gè)數(shù)據(jù)庫(kù)類即可管理本地?cái)?shù)據(jù)庫(kù)通信,也支持遠(yuǎn)程數(shù)據(jù)庫(kù)通信等。
- 數(shù)據(jù)庫(kù)線程支持執(zhí)行各種sql語(yǔ)句,包括單條和批量。
- 組件中的所有類打印信息、錯(cuò)誤信息、執(zhí)行結(jié)果都信號(hào)發(fā)出去。
- 集成數(shù)據(jù)庫(kù)通用翻頁(yè)類(負(fù)責(zé)具體處理邏輯),搭配分頁(yè)導(dǎo)航控件(負(fù)責(zé)外觀),形成超級(jí)牛逼的翻頁(yè)控件。
- 集成數(shù)據(jù)庫(kù)自動(dòng)清理類,設(shè)定最大記錄數(shù)后臺(tái)自動(dòng)清理早期數(shù)據(jù)。
- 集成自定義委托類,支持復(fù)選框、文本框、下拉框、日期框、微調(diào)框、進(jìn)度條等。
- 同時(shí)支持Qt4-Qt6,親測(cè)Qt4.6到Qt6.3任意版本,任意系統(tǒng)和編譯器。
- 本組件無(wú)故障 360天7乘24小時(shí) 運(yùn)行在至少上萬(wàn)個(gè)現(xiàn)場(chǎng),商業(yè)級(jí)別品質(zhì)保證。
- 每個(gè)類都對(duì)應(yīng)完整詳細(xì)的使用示例,注釋詳細(xì),非常適合閱讀學(xué)習(xí)。
- 可以作為獨(dú)立的程序運(yùn)行,比如自動(dòng)清理早期數(shù)據(jù),同步數(shù)據(jù)到云端。
- 全部線程處理,不卡界面,自動(dòng)重連數(shù)據(jù)庫(kù)。
- 普通測(cè)試情況,sqlite數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)發(fā)生器每秒鐘插入1000條記錄約0.003秒鐘,同時(shí)自動(dòng)清理數(shù)據(jù)類每秒鐘刪除1000條記錄約0.13秒,不同線程互不干擾。
三、體驗(yàn)地址
體驗(yàn)地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg 提取碼:uyes 文件名:bin_dbtool.zip
國(guó)內(nèi)站點(diǎn):https://gitee.com/feiyangqingyun
國(guó)際站點(diǎn):https://github.com/feiyangqingyun
四、效果圖
五、相關(guān)代碼
#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); //實(shí)例化數(shù)據(jù)庫(kù)通信類 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; //強(qiáng)制本程序帶的數(shù)據(jù)庫(kù) dbtool.db dbInfo.dbName = DbHelper::getDbDefaultFile(); dbConn->setConnInfo(DbHelper::getDbType("sqlite"), dbInfo); if (!dbConn->openDb()) { QUIHelper::showMessageBoxError("委托數(shù)據(jù)庫(kù)打開失敗!"); } } 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(); //設(shè)置新增加的行默認(rèn)值 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("保存信息失敗,請(qǐng)重新填寫!"); } //有些數(shù)據(jù)庫(kù)需要主動(dòng)查詢一下不然是空白的比如odbc數(shù)據(jù)源 model->select(); } void frmDbDelegate::on_btnDelete_clicked() { int row = ui->tableView->currentIndex().row(); if (row < 0) { QUIHelper::showMessageBoxError("請(qǐng)選擇要?jiǎng)h除的用戶!"); return; } if (QUIHelper::showMessageBoxQuestion("確定要?jiǎng)h除該用戶嗎? 刪除后不能恢復(fù)!") == 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(); } }
到此這篇關(guān)于Qt數(shù)據(jù)庫(kù)應(yīng)用之超級(jí)自定義委托的文章就介紹到這了,更多相關(guān)Qt自定義委托內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫(kù)分頁(yè)
- Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫(kù)清理
- Qt數(shù)據(jù)庫(kù)相關(guān)應(yīng)用開發(fā)總結(jié)
- Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)生成器
- Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)數(shù)據(jù)圖文混排
- Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)數(shù)據(jù)打印到紙張
- Qt數(shù)據(jù)庫(kù)應(yīng)用之?dāng)?shù)據(jù)打印到pdf
相關(guān)文章
Qt物聯(lián)網(wǎng)管理平臺(tái)之實(shí)現(xiàn)數(shù)據(jù)查詢導(dǎo)出打印
這篇文章主要為大家介紹了如何利用Qt編寫物聯(lián)網(wǎng)管理平臺(tái)中數(shù)據(jù)查詢導(dǎo)出打印的功能,文字的示例代碼講解詳細(xì),感興趣的可以了解一下2022-07-07C++如何獲取系統(tǒng)信息 C++獲取IP地址、硬件信息等
這篇文章主要為大家詳細(xì)介紹了C++如何獲取系統(tǒng)信,C++獲取IP地址、硬件信息等,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04C語(yǔ)言實(shí)現(xiàn)考勤管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)考勤管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02常用排序算法的C語(yǔ)言版實(shí)現(xiàn)示例整理
這篇文章主要介紹了常用排序算法的C語(yǔ)言版實(shí)現(xiàn)示例整理,包括快速排序及冒泡排序等,基本上都給出了時(shí)間復(fù)雜度,需要的朋友可以參考下2016-03-03C++ Cartographer加載配置文件過(guò)程介紹
這篇文章主要介紹了Cartographer加載配置文件過(guò)程,谷歌優(yōu)秀的激光SLAM開源框架Cartographer算法簡(jiǎn)單,但是程序部分太多需要學(xué)習(xí)的地方了,不論是整體框架的結(jié)構(gòu),還是數(shù)據(jù)的使用,都是非常優(yōu)美的2023-03-03