#include "FindPeaksResultDialog.h" #include "GlobalDefine.h" #include #include #include #include #include #include #include #include "csv.h" #include #include FindPeaksResultDialog::FindPeaksResultDialog(QWidget *parent) : QDialog(parent) { this->setWindowTitle(QString(QStringLiteral(u"寻峰结果"))); this->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); this->setWindowModality(Qt::WindowModal); this->setModal(false); QPushButton* btn_all_select = new QPushButton(QString(QStringLiteral(u"全选"))); QPushButton* btn_reserve_select = new QPushButton(QString(QStringLiteral(u"反选"))); QLabel* filter_channel_label = new QLabel(QString(QStringLiteral(u"筛选通道:"))); _filter_channel_combo_box = new QComboBox(); _filter_channel_combo_box->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); _filter_channel_combo_box->setMinimumWidth(75); _filter_channel_combo_box->addItem(QString(QStringLiteral(u"所有通道"))); _filter_channel_combo_box->setMaxVisibleItems(10); _filter_channel_combo_box->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); QPushButton* btn_save = new QPushButton(QString(QStringLiteral(u"保存"))); QHBoxLayout* top_layout = new QHBoxLayout(); top_layout->addWidget(btn_all_select); top_layout->addWidget(btn_reserve_select); top_layout->addSpacing(10); top_layout->addWidget(filter_channel_label); top_layout->addWidget(_filter_channel_combo_box); top_layout->addStretch(); top_layout->addWidget(btn_save); const QString& channel_col_name = QString(QStringLiteral(u"通道")); const QString& peak_pos_col_name = QString(QStringLiteral(u"峰位")); const QString& left_bound_col_name = QString(QStringLiteral(u"左边界")); const QString& right_bound_col_name = QString(QStringLiteral(u"右边界")); const QString& peak_width_col_name = QString(QStringLiteral(u"峰宽")); const QString& peak_height_col_name = QString(QStringLiteral(u"峰高")); const QString& peak_fwhm_col_name = QString(QStringLiteral(u"FWHM")); const QString& peak_area_col_name = QString(QStringLiteral(u"峰面积")); const QString& operation_col_name = QString(QStringLiteral(u"操作")); _peaks_result_table = new QTableWidget(); _peaks_result_table->setObjectName("peaks_result_table"); _peaks_result_table->setColumnCount(9); _peaks_result_table->setHorizontalHeaderLabels({ channel_col_name, peak_pos_col_name, left_bound_col_name, right_bound_col_name, peak_width_col_name, peak_height_col_name, peak_fwhm_col_name, peak_area_col_name, operation_col_name }); _peaks_result_table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); _peaks_result_table->horizontalHeader()->setSectionResizeMode(_peaks_result_table->columnCount() - 1, QHeaderView::ResizeToContents); _peaks_result_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); _peaks_result_table->setSelectionBehavior(QAbstractItemView::SelectRows); _peaks_result_table->setSelectionMode(QAbstractItemView::SingleSelection); _peaks_result_table->setEditTriggers(QTableWidget::NoEditTriggers); connect(_filter_channel_combo_box, &QComboBox::currentTextChanged, [this](const QString& text) { _peaks_result_table->setCurrentItem(nullptr); auto row_count = _peaks_result_table->rowCount(); if (text == QString(QStringLiteral(u"所有通道"))) { for (int i = 0; i < row_count - 1; i++) { _peaks_result_table->setRowHidden(i, false); } } else { for (int i = row_count - 1; i >= 0; i--) { const QString& channel = _peaks_result_table->item(i, 0)->text(); bool is_hidden = text == channel ? false : true; _peaks_result_table->setRowHidden(i, is_hidden); } } }); connect(btn_all_select, &QPushButton::clicked, [this]() { _peaks_result_table->setCurrentItem(nullptr); auto row_count = _peaks_result_table->rowCount(); for (int i = 0; i < row_count; i++) { if (_peaks_result_table->isRowHidden(i)) { continue; } auto item = _peaks_result_table->item(i, 0); if (item) { item->setCheckState(Qt::Checked); } } }); connect(btn_reserve_select, &QPushButton::clicked, [this]() { _peaks_result_table->setCurrentItem(nullptr); auto row_count = _peaks_result_table->rowCount(); for (int i = 0; i < row_count; i++) { if (_peaks_result_table->isRowHidden(i)) { continue; } auto item = _peaks_result_table->item(i, 0); if (item) { Qt::CheckState check_state = (item->checkState() == Qt::Checked) ? Qt::Unchecked : Qt::Checked; item->setCheckState(check_state); } } }); connect(btn_save, &QPushButton::clicked, [this]() { saveCurrentPeakResult(); }); connect(_peaks_result_table, &QTableWidget::itemChanged, [this](QTableWidgetItem* item) { bool is_watch_item_changed = _peaks_result_table->property("WatchItemChanged").toBool(); if (is_watch_item_changed && bool(item->column() == 0)) { bool b_show_peak = (item->checkState() == Qt::Checked); emit peakInfoChanged(peakInfo(item, b_show_peak, false)); } }); connect(_peaks_result_table, &QTableWidget::currentItemChanged, [this](QTableWidgetItem* current, QTableWidgetItem* previous) { bool is_watch_item_changed = _peaks_result_table->property("WatchItemChanged").toBool(); if (is_watch_item_changed) { int previous_row = -1; if (previous ) { previous_row = previous->row(); } int current_row = -1; if (current) { current_row = current->row(); } if ((previous_row >= 0) && (previous_row != current_row) ) { emit peakInfoChanged(peakInfo(previous, false, false)); } if (current_row >= 0) { emit peakInfoChanged(peakInfo(current, true, true)); } } }); QVBoxLayout* layout = new QVBoxLayout(this); layout->addLayout(top_layout); layout->addWidget(_peaks_result_table); } FindPeaksResultDialog::~FindPeaksResultDialog() { qDebug() << "~FindPeaksResultDialog"; } void FindPeaksResultDialog::SetPeakResultDataFilename(const QString &data_filename) { this->_peaks_result_data_filename = data_filename; } void FindPeaksResultDialog::SetChannelNameList(const QStringList &ch_name_list) { _filter_channel_combo_box->clear(); _filter_channel_combo_box->addItem(QString(QStringLiteral(u"所有通道"))); _filter_channel_combo_box->addItems(ch_name_list); } void FindPeaksResultDialog::UpdatePeakResult() { if (!QFileInfo(_peaks_result_data_filename).exists()) return; _peaks_result_table->setCurrentItem(nullptr); _peaks_result_table->setProperty("WatchItemChanged", false); auto row_count = _peaks_result_table->rowCount(); for (int i = row_count - 1; i >= 0; i--) { _peaks_result_table->removeRow(i); } const QString& channel_col_name = QString(QStringLiteral(u"通道")); const QString& peak_pos_col_name = QString(QStringLiteral(u"峰位")); const QString& left_bound_col_name = QString(QStringLiteral(u"左边界")); const QString& right_bound_col_name = QString(QStringLiteral(u"右边界")); const QString& peak_width_col_name = QString(QStringLiteral(u"峰宽")); const QString& peak_height_col_name = QString(QStringLiteral(u"峰高")); const QString& peak_fwhm_col_name = QString(QStringLiteral(u"FWHM")); const QString& peak_area_col_name = QString(QStringLiteral(u"峰面积")); io::CSVReader< 8, io::trim_chars<' ', '\t'>, io::double_quote_escape<',', '"'>, io::throw_on_overflow, io::empty_line_comment> reader(QStrToSysPath(_peaks_result_data_filename)); reader.read_header( io::ignore_extra_column, channel_col_name.toStdString(), peak_pos_col_name.toStdString(), left_bound_col_name.toStdString(), right_bound_col_name.toStdString(), peak_width_col_name.toStdString(), peak_height_col_name.toStdString(), peak_fwhm_col_name.toStdString(), peak_area_col_name.toStdString()); std::string ch_name; int peak_pos; int left_bound, right_bound, peak_width, peak_height, peak_fwhm; double peak_area; while (reader.read_row(ch_name, peak_pos, left_bound, right_bound, peak_width, peak_height, peak_fwhm, peak_area)) { if (!ch_name.empty()) { int row = _peaks_result_table->rowCount(); _peaks_result_table->insertRow(row); _peaks_result_table->setItem(row, 0, new QTableWidgetItem(QString::fromStdString(ch_name))); _peaks_result_table->item(row, 0)->setCheckState(Qt::Unchecked); _peaks_result_table->setItem(row, 1, new QTableWidgetItem(QString::number(peak_pos))); _peaks_result_table->setItem(row, 2, new QTableWidgetItem(QString::number(left_bound))); _peaks_result_table->setItem(row, 3, new QTableWidgetItem(QString::number(right_bound))); _peaks_result_table->setItem(row, 4, new QTableWidgetItem(QString::number(peak_width))); _peaks_result_table->setItem(row, 5, new QTableWidgetItem(QString::number(peak_height))); _peaks_result_table->setItem(row, 6, new QTableWidgetItem(QString::number(peak_fwhm))); _peaks_result_table->setItem(row, 7, new QTableWidgetItem(QString::number(peak_area))); QTableWidgetItem* item = new QTableWidgetItem; _peaks_result_table->setItem(row, 8, item); QPushButton* btn_remove_row = new QPushButton(QStringLiteral(u"删除")); btn_remove_row->setMaximumWidth(35); connect(btn_remove_row, &QPushButton::clicked, [this, item, btn_remove_row]() { int remove_row = item->row(); this->_peaks_result_table->item(remove_row, 0)->setCheckState(Qt::Unchecked); emit peakInfoChanged(peakInfo(item, false, false)); this->_peaks_result_table->removeRow(remove_row); btn_remove_row->deleteLater(); }); _peaks_result_table->setCellWidget(row, 8, btn_remove_row); } } _peaks_result_table->setProperty("WatchItemChanged", true); } QAbstractTableModel* FindPeaksResultDialog::GetPeakResultDataModel() const { QAbstractTableModel* peaks_result_model = dynamic_cast(_peaks_result_table->model()); return peaks_result_model; } void FindPeaksResultDialog::saveCurrentPeakResult() { std::ofstream out_file(QStrToSysPath(_peaks_result_data_filename)); std::string channel_str = QString(QStringLiteral(u"通道")).toStdString(); std::string addr_str = QString(QStringLiteral(u"峰位")).toStdString(); std::string left_addr_str = QString(QStringLiteral(u"左边界")).toStdString(); std::string lright_addr_str = QString(QStringLiteral(u"右边界")).toStdString(); std::string width_str = QString(QStringLiteral(u"峰宽")).toStdString(); std::string height_str = QString(QStringLiteral(u"峰高")).toStdString(); std::string fwhm_str = QString(QStringLiteral(u"FWHM")).toStdString(); std::string area_str = QString(QStringLiteral(u"峰面积")).toStdString(); out_file << channel_str << "," << addr_str << "," << left_addr_str << "," << lright_addr_str << "," << width_str << "," << height_str << "," << fwhm_str << "," << area_str << "\n"; auto row_count = _peaks_result_table->rowCount(); for (int i = 0; i < row_count; i++) { std::string channel = _peaks_result_table->item(i, 0)->text().toStdString(); int peak_pos = _peaks_result_table->item(i, 1)->text().toInt(); int left_bound = _peaks_result_table->item(i, 2)->text().toInt(); int right_bound = _peaks_result_table->item(i, 3)->text().toInt(); int peak_width = _peaks_result_table->item(i, 4)->text().toInt(); int peak_height = _peaks_result_table->item(i, 5)->text().toInt(); int peak_fwhm = _peaks_result_table->item(i, 6)->text().toInt(); double peak_area = _peaks_result_table->item(i, 7)->text().toDouble(); out_file << channel << "," << peak_pos << "," << left_bound << "," << right_bound << "," << peak_width << "," << peak_height << "," << peak_fwhm<< "," << peak_area << "\n"; } LOG_INFO(QStringLiteral(u"保存峰信息完成.")); } QVariantMap FindPeaksResultDialog::peakInfo(QTableWidgetItem *item, bool show_peak, bool show_peak_area) { QVariantMap peak_infos; if (!item) { return peak_infos; } int row = item->row(); bool is_checked = bool(_peaks_result_table->item(row, 0)->checkState() == Qt::Checked); const QString& channel = _peaks_result_table->item(row, 0)->text(); int peak_pos = _peaks_result_table->item(row, 1)->text().toInt(); int left_bound = _peaks_result_table->item(row, 2)->text().toInt(); int right_bound = _peaks_result_table->item(row, 3)->text().toInt(); int peak_width = _peaks_result_table->item(row, 4)->text().toInt(); int peak_height = _peaks_result_table->item(row, 5)->text().toInt(); int peak_fwhm = _peaks_result_table->item(row, 6)->text().toInt(); double peak_area = _peaks_result_table->item(row, 7)->text().toDouble(); peak_infos["channel"] = channel; peak_infos["peak_pos"] = peak_pos; peak_infos["left_bound"] = left_bound; peak_infos["right_bound"] = right_bound; peak_infos["peak_width"] = peak_width; peak_infos["peak_height"] = peak_height; peak_infos["peak_fwhm"] = peak_fwhm; peak_infos["peak_area"] = peak_area; peak_infos["checked"] = is_checked || show_peak; peak_infos["show_peak_area"] = show_peak_area && show_peak; return peak_infos; }