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