1 前言
最近做了一個對Json文件進行屬性鍵值增刪、修改的小工具。這里總結一下遇到的一些較為麻煩的問題,以及踩過的一些坑,方便自己回顧。也希望能讓需要的人可以少繞些彎路。工具(如下圖)主要功能為:讀取路徑下所有Json文件,並將所有Json文件文件名顯示至QListWidget,單擊QlistWidget中的Json文件時顯示Json文件具體數據至QtableWidget,右鍵增刪屬性行,對Json文件中的數據進行修改后進行保存。下拉框中的屬性名稱由Json文件讀入。
2 問題總結
(1)QTableWidget指定行列添加TableWidgetItem?
ui->tableWidget->setItem(Row,Column,new QTableWidgetItem(QString itemName));//itemName為需要顯示的內容
(2)判斷鼠標是否在QTableWidget內,進行右鍵操作事件?
///右鍵菜單顯示 void DisJsonParam::contextMenuEvent(QContextMenuEvent *event) { QPoint i = ui->tableWidget->mapFromGlobal(event->globalPos()); QRect rect(QPoint(0, 0), ui->tableWidget->size()); if (rect.contains(i)) { _tableWidgetMenu->exec(event->globalPos()); } }
(3)QTableWidget右鍵插入行,刪除行?//與(2)一同組成右鍵增刪行功能
QMenu *_tableWidgetMenu = nullptr;
QAction *addProperty = new QAction("add Property", this); QAction *delProperty = new QAction("del Property", this);
_tableWidgetMenu ->addAction(addProperty);
_tableWidgetMenu->addAction(delProperty);
connect(addProperty, &QAction::triggered, this, &DisJsonParam::addPropertyClicked);
connect(delProperty, &QAction::triggered, this, &DisJsonParam::delPropertyClicked);
void DisJsonParam::delPropertyClicked() { ui->tableWidget->removeRow(rowIndex);//RowIndex為需要移除的行數 }
void DisJsonParam::addPropertyClicked() { int row = ui->tableWidget->rowCount(); ui->tableWidget->insertRow(row);//在最后一行底部插入 }
(4)QListWidget顯示某路徑下特定格式文件的所有文件名?
void DisJsonParam::listJsonFiles() { if(_folderPath.isEmpty())//_folderPath為文件所在路徑 { QMessageBox::information(this,"提示","路徑錯誤!"); return; } QDir dir = QFileInfo(_folderPath).absolutePath(); //QFileInfoList infoList = dir.entryInfoList(QDir::Files);//與addItems搭配使用 ui->listWidget->clear(); QStringList list = dir.entryList(); QString jsonName; for (int index = 0; index < list.size(); index++) { jsonName = list.at(index); QFileInfo fileinfo = QFileInfo(jsonName); QString suffix = fileinfo.suffix(); if (suffix == "json")//指定格式文件過濾 { ui->listWidget->addItem(jsonName); } } //ui->listWidget->addItems(list);//可一次性將文件列表顯示出來 但會包含其它格式的文件 }
(5)關閉軟件界面或切換文件時詢問是否保存修改后的文件?
///若tablewidget發生修改 則在切換json文件或退出widget時詢問是否將修改后的數據寫入json文件 void DisJsonParam::saveJsonObj2JsonFile() { if(changedFlag) { QMessageBox::StandardButton selectKey; selectKey = QMessageBox::question(this, "提示", "文件已被修改,是否保存修改?", QMessageBox::Yes|QMessageBox::No, QMessageBox::NoButton); if (selectKey==QMessageBox::Yes) { QJsonDocument jsonDoc(_currentJsonObj); QString jsonString = jsonDoc.toJson(); QFile saveFile(_folderPath + _currentFileName); if(!saveFile.open(QIODevice::WriteOnly)) { QMessageBox::information(this,"提示","無法保存Json文件"); return; } saveFile.write(jsonString.toLocal8Bit()); saveFile.close(); } changedFlag = false; } }
(6)從Json文件中批量添加Item至CoboBox下拉選項,並給每個下拉選項增加Tip提示?
///獲取Json文件中的屬性鍵值,往comboBox添加Items並顯示itemTips,showName為初始化顯示在comboBox上的名稱 void DisJsonParam::addPropertiesAndTipsFromJson(QString prptesJsonFilePath,QString showName,QComboBox *comboBox) { QFile file(prptesJsonFilePath); file.open(QIODevice::ReadOnly | QIODevice::Text); QString value = file.readAll(); file.close(); QJsonParseError parseJsonErr; QJsonDocument propertiesJsonDoc = QJsonDocument::fromJson(value.toUtf8(), &parseJsonErr); if (! (parseJsonErr.error == QJsonParseError::NoError)) { QMessageBox::information(this,"提示","無法讀取Json文件"); return; } QJsonObject propertiesJsonObj = propertiesJsonDoc.object(); QStringList keyNameList = propertiesJsonObj.keys(); keyNameList.removeOne(showName); QStandardItemModel *model = new QStandardItemModel(this); QStandardItem *item; item = new QStandardItem(showName); item->setToolTip(propertiesJsonObj[showName].toString()); model->appendRow(item); for (int i = 0;i < keyNameList.size();i++) { item = new QStandardItem(keyNameList[i]); item->setToolTip(propertiesJsonObj[keyNameList[i]].toString()); model->appendRow(item); } comboBox->setModel(model); }
(7)TableWidget動態添加QComboBox?
QComboBox *propertiesCombobox = new QComboBox(); addPropertiesAndTipsFromJson(_prptesJsonFilePath,key["propertyName"].toString(),propertiesCombobox);//調用(5) connect(propertiesCombobox, SIGNAL(currentIndexChanged(QString)), this, SLOT(saveChange2JsonObj()));//每個控件均連接信號以便數據交互
ui->tableWidget->setCellWidget(i,j,propertiesCombobox);//i為所在行數,j為所在列數
(8)TableWidget動態添加QSpinBox(QDoubleSpinBox)?
QDoubleSpinBox *upperSpinBoxItem = new QDoubleSpinBox(); upperSpinBoxItem->setRange(-9999999999,9999999999);//設置數值顯示范圍 upperSpinBoxItem->setValue(key["upper"].toDouble()); connect(upperSpinBoxItem, SIGNAL(valueChanged(double)), this, SLOT(saveChange2JsonObj()));//每個控件均連接信號以便數據交互
ui->tableWidget->setCellWidget(i,j+2,upperSpinBoxItem);//i為所在行,j+2為所在列