#include "DeviceParamsTableForm.h" #include "ui_DeviceParamsTableForm.h" #include "GlobalDefine.h" #include #include #include #include #include #include #include #include #include #include #include #include "DeviceParamsSaveToSysDlg.h" static QStringList s_addr_count_list { "256", "512", "1024", "2048", "4096", "8192", "16384" }; static QMap s_transfer_mode_list { { 1, QStringLiteral(u"波形模式") }, { 2, QStringLiteral(u"ADC模式") }, { 3, QStringLiteral(u"粒子模式") } }; static QStringList s_device_gain_list { "1", "2", "4", "8", "16" }; DeviceParamsItemDelegate::DeviceParamsItemDelegate(QObject* parent) : QStyledItemDelegate(parent) { } QWidget* DeviceParamsItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { QWidget* editor = nullptr; int col = index.column(); switch (col) { case 1: { // 多道分辨率 QComboBox *combobox = new QComboBox(parent); for (int index = 0; index < s_addr_count_list.size(); ++index) { QString value = s_addr_count_list.at(index); combobox->addItem(value); } editor = combobox; } break; case 2: { // 数据模式 QComboBox *combobox = new QComboBox(parent); QList transfer_mode_list = s_transfer_mode_list.keys(); qSort(transfer_mode_list.rbegin(), transfer_mode_list.rend()); foreach (int transfer_mode, transfer_mode_list) { combobox->addItem(s_transfer_mode_list.value(transfer_mode), transfer_mode); } editor = combobox; } break; case 3: { // 硬件增益 QComboBox *combobox = new QComboBox(parent); for (int index = 0; index < s_device_gain_list.size(); ++index) { QString value = s_device_gain_list.at(index); combobox->addItem(value, index + 1); } editor = combobox; } break; case 4: { // 软件增益 QSpinBox* spinbox = new QSpinBox(parent); spinbox->setRange(1, 2^32-1); editor = spinbox; } break; case 5: { // 时间常数 QDoubleSpinBox* spinbox = new QDoubleSpinBox(parent); spinbox->setRange(1, 100); editor = spinbox; } break; case 6: { // 直流偏移 QSpinBox* spinbox = new QSpinBox(parent); spinbox->setRange(-1000, 1000); editor = spinbox; } break; case 7: { // 成形时间 QSpinBox* spinbox = new QSpinBox(parent); spinbox->setRange(1, 10); editor = spinbox; } break; case 8: { // 快通道触发阈值 QDoubleSpinBox* spinbox = new QDoubleSpinBox(parent); spinbox->setRange(0, 1000); editor = spinbox; } break; case 9: { // CR微分模式 QComboBox *combobox = new QComboBox(parent); combobox->addItem(QStringLiteral(u"启用"), true); combobox->addItem(QStringLiteral(u"禁用"), false); editor = combobox; } break; case 10: { // 输入信号正负极性选择 QComboBox *combobox = new QComboBox(parent); combobox->addItem(QStringLiteral(u"启用"), true); combobox->addItem(QStringLiteral(u"禁用"), false); editor = combobox; } break; default: break; } return editor; } void DeviceParamsItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { QVariant value = index.data(Qt::EditRole); int col = index.column(); switch (col) { case 1: case 2: case 3: { QComboBox *combo = qobject_cast(editor); if (combo) { int idx = combo->findText(value.toString()); if (idx >= 0) combo->setCurrentIndex(idx); } } break; case 4: { QSpinBox *spinbox = qobject_cast(editor); if (spinbox) { spinbox->setValue(value.toUInt()); } } break; case 5: { QDoubleSpinBox *spinbox = qobject_cast(editor); if (spinbox) { spinbox->setValue(value.toDouble()); } } break; case 6: case 7: { QSpinBox *spinbox = qobject_cast(editor); if (spinbox) { spinbox->setValue(value.toUInt()); } } break; case 8: { QDoubleSpinBox *spinbox = qobject_cast(editor); if (spinbox) { spinbox->setValue(value.toDouble()); } } break; case 9: case 10: { QComboBox *combo = qobject_cast(editor); if (combo) { int idx = combo->findText(value.toString()); if (idx >= 0) combo->setCurrentIndex(idx); } } break; default: break; } } void DeviceParamsItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { int col = index.column(); switch (col) { case 1: case 2: case 3: { QComboBox *combobox = qobject_cast(editor); if (combobox) { model->setData(index, combobox->currentText()); } } break; case 4: { QSpinBox *spinbox = qobject_cast(editor); if (spinbox) { model->setData(index, spinbox->value()); } } break; case 5: { QDoubleSpinBox *spinbox = qobject_cast(editor); if (spinbox) { model->setData(index, spinbox->value()); } } break; case 6: case 7: { QSpinBox *spinbox = qobject_cast(editor); if (spinbox) { model->setData(index, spinbox->value()); } } break; case 8: { QDoubleSpinBox *spinbox = qobject_cast(editor); if (spinbox) { model->setData(index, spinbox->value()); } } break; case 9: case 10: { QComboBox *combobox = qobject_cast(editor); if (combobox) { model->setData(index, combobox->currentText()); } } break; default: break; } } void DeviceParamsItemDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { editor->setGeometry(option.rect); } bool DeviceParamsItemDelegate::eventFilter(QObject* obj, QEvent* event) { return QStyledItemDelegate::eventFilter(obj, event); } DeviceParamsTableForm::DeviceParamsTableForm(QWidget* parent) : QWidget(parent) , ui(new Ui::DeviceParamsTableForm) { ui->setupUi(this); ui->params_cfg_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->params_cfg_table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); ui->params_cfg_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); ui->params_cfg_table->setItemDelegate(new DeviceParamsItemDelegate(this)); for (int row = 0; row < 32; ++row) { int channel_num = row + 1; int board_id = (channel_num - 1) / 4; int channel_id = (channel_num - 1) % 4; QVariantMap channel_info; channel_info["board_id"] = board_id; channel_info["channel_id"] = channel_id; ui->params_cfg_table->insertRow(row); const QString& channel_text = QStringLiteral(u"通道%1").arg(channel_num); ui->params_cfg_table->setItem(row, 0, new QTableWidgetItem(channel_text)); ui->params_cfg_table->item(row, 0)->setCheckState(Qt::Unchecked); ui->params_cfg_table->item(row, 0)->setData(Qt::UserRole, channel_info); ui->params_cfg_table->setItem(row, 1, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 2, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 3, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 4, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 5, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 6, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 7, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 8, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 9, new QTableWidgetItem()); ui->params_cfg_table->setItem(row, 10, new QTableWidgetItem()); } connect(ui->btn_all_select, &QPushButton::clicked, this, &DeviceParamsTableForm::onAllSelectBtnClicked); connect(ui->btn_reserve_select, &QPushButton::clicked, this, &DeviceParamsTableForm::onReserveSelectBtnClicked); connect(ui->btn_channel_select, &QPushButton::clicked, this, &DeviceParamsTableForm::onCfgChannelSelectBtnClicked); connect(ui->btn_update_to_other, &QPushButton::clicked, this, &DeviceParamsTableForm::onCurrentChannelToOther); connect(ui->btn_save, &QPushButton::clicked, this, &DeviceParamsTableForm::onSaveSelectedChannelConfig); connect(ui->btn_save_to_sys, &QPushButton::clicked, this, &DeviceParamsTableForm::onSaveSelectedChannelConfigToSys); } DeviceParamsTableForm::~DeviceParamsTableForm() { delete ui; } void DeviceParamsTableForm::SetConfigFilename(const QString& filename) { _config_filename = filename; if ( _config_filename.isEmpty() ) { return; } QFile json_file(_config_filename); if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } QByteArray json_data = json_file.readAll(); json_file.close(); QJsonDocument json_doc = QJsonDocument::fromJson(json_data); if (json_doc.isNull()) { return; } if (!json_doc.isObject()) return; QVariantMap device_config_info = json_doc.object().toVariantMap(); if (device_config_info.contains(QStringLiteral(u"ParamsConfigureInfo"))) { QVariantMap config_info = device_config_info[QStringLiteral(u"ParamsConfigureInfo")].toMap(); if (config_info.contains(QStringLiteral(u"Name"))) { this->_cfg_name = config_info[QStringLiteral(u"Name")].toString(); } if (config_info.contains(QStringLiteral(u"Description"))) { this->_cfg_description = config_info[QStringLiteral(u"Description")].toString(); } } this->ClearParamsTable(); if (!device_config_info.contains(QStringLiteral(u"ChannelConfig"))) return; QVariantList channel_config_list = device_config_info[QStringLiteral(u"ChannelConfig")].toList(); if (channel_config_list.isEmpty()) return; for (auto channel_config : channel_config_list) { if (!channel_config.isValid()) continue; QVariantMap channel_config_info = channel_config.toMap(); if (!channel_config_info.contains("BoardId") || !channel_config_info.contains("ChannelId")) continue; int board_id = channel_config_info["BoardId"].toInt(); int channel_id = channel_config_info["ChannelId"].toInt(); int row = board_id * 4 + channel_id; if (row >= 32) continue; // QVariantMap channel_info; // channel_info["board_id"] = board_id; // channel_info["channel_id"] = channel_id; // ui->params_cfg_table->item(row, 0)->setData(Qt::UserRole, channel_info); if (channel_config_info.contains("AddrCount")) ui->params_cfg_table->item(row, 1)->setText(channel_config_info["AddrCount"].toString()); if (channel_config_info.contains("TransferMode")) { int transfer_mode = channel_config_info["TransferMode"].toInt(); ui->params_cfg_table->item(row, 2)->setText(s_transfer_mode_list.value(transfer_mode)); } if (channel_config_info.contains("DeviceGain")) ui->params_cfg_table->item(row, 3)->setText(channel_config_info["DeviceGain"].toString()); // if (channel_config_info.contains("DeviceGainSelectIndex")) // ui->params_cfg_table->item(row, 3)->setData(Qt::UserRole, channel_config_info["DeviceGainSelectIndex"]); if (channel_config_info.contains("SoftGain")) ui->params_cfg_table->item(row, 4)->setText(channel_config_info["SoftGain"].toString()); if (channel_config_info.contains("TimeConst")) ui->params_cfg_table->item(row, 5)->setText(channel_config_info["TimeConst"].toString()); if (channel_config_info.contains("DcOffset")) ui->params_cfg_table->item(row, 6)->setText(channel_config_info["DcOffset"].toString()); if (channel_config_info.contains("FormTime")) ui->params_cfg_table->item(row, 7)->setText(channel_config_info["FormTime"].toString()); if (channel_config_info.contains("FastChannelTrigerValue")) ui->params_cfg_table->item(row, 8)->setText(channel_config_info["FastChannelTrigerValue"].toString()); if (channel_config_info.contains("CRDivMode")) { bool CRDiv_mode = channel_config_info["CRDivMode"].toBool(); ui->params_cfg_table->item(row, 9)->setText(CRDiv_mode ? QStringLiteral(u"启用") : QStringLiteral(u"禁用")); } if (channel_config_info.contains("InputSignalPostive")) { bool input_signal_postive = channel_config_info["InputSignalPostive"].toBool(); ui->params_cfg_table->item(row, 10)->setText(input_signal_postive ? QStringLiteral(u"启用") : QStringLiteral(u"禁用")); } } } void DeviceParamsTableForm::SetButtonEnable(bool enable) { ui->btn_save->setVisible(enable); ui->btn_save_to_sys->setVisible(enable); } const QString &DeviceParamsTableForm::GetConfigName() const { return _cfg_name; } const QString &DeviceParamsTableForm::GetConfigDescription() const { return _cfg_description; } void DeviceParamsTableForm::onAllSelectBtnClicked() { for (int row = 0; row < 32; ++row) { if (ui->params_cfg_table->isRowHidden(row)) continue; ui->params_cfg_table->item(row, 0)->setCheckState(Qt::Checked); } } void DeviceParamsTableForm::onReserveSelectBtnClicked() { for (int row = 0; row < 32; ++row) { if (ui->params_cfg_table->isRowHidden(row)) continue; auto item = ui->params_cfg_table->item(row, 0); Qt::CheckState check_state = item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked; item->setCheckState(check_state); } } void DeviceParamsTableForm::onCfgChannelSelectBtnClicked() { QDialog cfg_channel_select_dlg(this, Qt::Dialog | Qt::WindowCloseButtonHint); cfg_channel_select_dlg.setWindowTitle(QString(QStringLiteral(u"设备测量参数配置通道选择"))); cfg_channel_select_dlg.setWindowModality(Qt::WindowModal); cfg_channel_select_dlg.setModal(true); QVBoxLayout* layout = new QVBoxLayout(&cfg_channel_select_dlg); // 自动计算多列排布 int num_columns = std::sqrt(32); if (num_columns == 0) num_columns = 1; QList all_checkboxes; QVBoxLayout* checkbox_layout = new QVBoxLayout(); QHBoxLayout* checkbox_column_layout = new QHBoxLayout(); for (int row = 0; row < 32; ++row) { QCheckBox* check_box = new QCheckBox(QStringLiteral(u"通道%1").arg(row + 1)); check_box->setChecked(!ui->params_cfg_table->isRowHidden(row)); checkbox_column_layout->addWidget(check_box); all_checkboxes.append(check_box); connect(check_box, &QCheckBox::stateChanged, [this, row](int state) { ui->params_cfg_table->setRowHidden(row, state == Qt::Unchecked); }); if (checkbox_column_layout->count() >= num_columns) { checkbox_layout->addLayout(checkbox_column_layout); checkbox_column_layout = new QHBoxLayout(); } } if (checkbox_column_layout->count() < num_columns) { checkbox_column_layout->addStretch(); } checkbox_layout->addLayout(checkbox_column_layout); // 全选和反选 QHBoxLayout* button_layout = new QHBoxLayout(); QPushButton* btn_all_select = new QPushButton(QString(QStringLiteral(u"全选"))); connect(btn_all_select, &QPushButton::clicked, [this, all_checkboxes]() { for (int row = 0; row < 32; ++row) { ui->params_cfg_table->setRowHidden(row, false); all_checkboxes[row]->setChecked(true); } }); button_layout->addWidget(btn_all_select); QPushButton* btn_reserve_select = new QPushButton(QString(QStringLiteral(u"反选"))); connect(btn_reserve_select, &QPushButton::clicked, [this, all_checkboxes]() { for (int row = 0; row < 32; ++row) { ui->params_cfg_table->setRowHidden(row, !ui->params_cfg_table->isRowHidden(row)); all_checkboxes[row]->setChecked(!all_checkboxes[row]->isChecked()); } }); button_layout->addWidget(btn_reserve_select); layout->addLayout(button_layout); layout->addLayout(checkbox_layout); cfg_channel_select_dlg.exec(); } void DeviceParamsTableForm::onCurrentChannelToOther() { int current_row = ui->params_cfg_table->currentRow(); for (int row = 0; row < 32; ++row) { if (ui->params_cfg_table->isRowHidden(row)) continue; if (ui->params_cfg_table->item(row, 0)->checkState() == Qt::Checked) { for (int col = 1; col < ui->params_cfg_table->columnCount(); ++col) { QTableWidgetItem* current_item = ui->params_cfg_table->item(current_row, col); if (current_item) { const QString& current_value = current_item->text(); ui->params_cfg_table->item(row, col)->setText(current_value); } } } } } void DeviceParamsTableForm::onSaveSelectedChannelConfig() { if (SaveSelectedChannelConfig(this->_config_filename, this->_cfg_name, this->_cfg_description)) { emit deviceConfigParamsSaved(this->_config_filename); } } void DeviceParamsTableForm::onSaveSelectedChannelConfigToSys() { int selected_channel_count = 0; for (int row = 0; row < 32; ++row) { if (ui->params_cfg_table->item(row, 0)->checkState() == Qt::Checked) { ++selected_channel_count; } } if (0 == selected_channel_count) { QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择需要保存的测量设备通道配置参数!")); return; } DeviceParamsSaveToSysDlg params_save_to_sys_dlg; if (QDialog::Accepted == params_save_to_sys_dlg.exec()) { const QString& device_params_dir_path = QDir(qApp->applicationDirPath()).filePath("configure/DeviceParams"); const QString params_cfg_name = params_save_to_sys_dlg.GetCfgName(); const QString params_cfg_description = params_save_to_sys_dlg.GetCfgDescription(); const QString params_cfg_filename = QDir(device_params_dir_path).filePath(params_cfg_name) + ".mscfg"; if (QFile::exists(params_cfg_filename)) { QMessageBox::warning(this, QStringLiteral(u"警告"), QStringLiteral(u"设备测量参数配置\"%1\"已存在!").arg(params_cfg_name)); } else { if (this->SaveSelectedChannelConfig(params_cfg_filename, params_cfg_name, params_cfg_description)) { this->_cfg_name = params_cfg_name; this->_cfg_description = params_cfg_description; QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"保存设备测量参数配置\"%1\"完成").arg(params_cfg_name)); } } } } bool DeviceParamsTableForm::SaveSelectedChannelConfig(const QString &save_filename, const QString& cfg_name, const QString& description) { QVariantList device_channel_params_list; for (int row = 0; row < 32; ++row) { if (ui->params_cfg_table->item(row, 0)->checkState() == Qt::Checked) { QVariantMap channel_info = ui->params_cfg_table->item(row, 0)->data(Qt::UserRole).toMap(); int board_id = channel_info["board_id"].toInt(); int channel_id = channel_info["channel_id"].toInt(); int addr_count = ui->params_cfg_table->item(row, 1)->text().toInt(); auto transfer_mode_value = [](const QString& transfer_mode_text) { int transfer_mode = 3; for (QMap::iterator it = s_transfer_mode_list.begin(); it != s_transfer_mode_list.end(); ++it) { if (it.value() == transfer_mode_text) { transfer_mode = it.key(); break; } } return transfer_mode; }; int transfer_mode = transfer_mode_value(ui->params_cfg_table->item(row, 2)->text()); int device_gain = ui->params_cfg_table->item(row, 3)->text().toInt(); int device_gain_index = s_device_gain_list.indexOf(ui->params_cfg_table->item(row, 3)->text()) + 1; uint soft_gain = ui->params_cfg_table->item(row, 4)->text().toUInt(); double time_const = ui->params_cfg_table->item(row, 5)->text().toDouble(); int dc_offset = ui->params_cfg_table->item(row, 6)->text().toInt(); int form_time = ui->params_cfg_table->item(row, 7)->text().toInt(); double fast_channel_triger_value = ui->params_cfg_table->item(row, 8)->text().toDouble(); auto is_enable = [](const QString& text) { bool enable = false; if (QStringLiteral(u"启用") == text) { enable = true; } else if (QStringLiteral(u"禁用") == text) { enable = false; } return enable; }; bool CRDiv_mode = is_enable(ui->params_cfg_table->item(row, 9)->text()); bool input_signal_postive = is_enable(ui->params_cfg_table->item(row, 10)->text()); QVariantMap device_channel_params; device_channel_params["BoardId"] = board_id; device_channel_params["ChannelId"] = channel_id; device_channel_params["AddrCount"] = addr_count; device_channel_params["TransferMode"] = transfer_mode; device_channel_params["DeviceGain"] = device_gain; device_channel_params["DeviceGainSelectIndex"] = device_gain_index; device_channel_params["SoftGain"] = soft_gain; device_channel_params["TimeConst"] = time_const; device_channel_params["DcOffset"] = dc_offset; device_channel_params["FormTime"] = form_time; device_channel_params["FastChannelTrigerValue"] = fast_channel_triger_value; device_channel_params["CRDivMode"] = CRDiv_mode; device_channel_params["InputSignalPostive"] = input_signal_postive; device_channel_params_list.append(device_channel_params); } } // if (device_channel_params_list.isEmpty()) { // QMessageBox::information(this, QStringLiteral(u"提示"), QStringLiteral(u"请选择需要保存的测量设备通道配置参数!")); // return false; // } QVariantMap device_config_info; if (!cfg_name.isEmpty()) { QVariantMap cfg_info; cfg_info["Name"] = cfg_name; cfg_info["Description"] = description; device_config_info["ParamsConfigureInfo"] = cfg_info; } device_config_info["ChannelConfig"] = device_channel_params_list; QJsonDocument json_doc = QJsonDocument::fromVariant(device_config_info); QFile json_file(save_filename); if (!json_file.open(QIODevice::WriteOnly | QIODevice::Text)) { return false; } json_file.write(json_doc.toJson()); json_file.close(); LOG_INFO(QStringLiteral(u"测量设备参数配置保存完成: %1.").arg(save_filename)); return true; } void DeviceParamsTableForm::ClearParamsTable() { for (int row = 0; row < ui->params_cfg_table->rowCount(); ++row) { for (int col = 1; col < ui->params_cfg_table->columnCount(); ++col) { ui->params_cfg_table->item(row, col)->setText(QString()); } } }