diff --git a/800X600_New_SystemProject-_NewInterface.zip b/800X600_New_SystemProject-_NewInterface.zip new file mode 100644 index 0000000..5fa7cd1 Binary files /dev/null and b/800X600_New_SystemProject-_NewInterface.zip differ diff --git a/QtUI.pro b/QtUI.pro index 8237b6f..8dd49da 100644 --- a/QtUI.pro +++ b/QtUI.pro @@ -132,6 +132,10 @@ HEADERS += Public.h \ scene/BarcodeEditor.h \ scene/DateFormatEditor.h \ scene/ViewModels.h \ + scene/CounterEditor.h \ + scene/ItemCommon.h \ + scene/DlgBarcodeFormat.h \ + scene/DlgQrcodeFormat.h \ CounterVarSet.h \ SystemUpdate.h \ dialogmaintenancetimesetting.h \ @@ -203,6 +207,9 @@ FORMS += \ scene/BarcodeEditor.ui \ scene/DateFormatEditor.ui \ scene/DateReplaceEditor.ui \ + scene/CounterEditor.ui \ + scene/DlgBarcodeFormat.ui \ + scene/DlgQrcodeFormat.ui \ dlgQrCode.ui SOURCES +=\ @@ -255,6 +262,10 @@ SOURCES +=\ scene/PicCounterItem.cpp \ scene/ViewModels.cpp \ scene/DateReplaceEditor.cpp \ + scene/CounterEditor.cpp \ + scene/ItemCommon.cpp \ + scene/DlgBarcodeFormat.cpp \ + scene/DlgQrcodeFormat.cpp \ DialogSaveFile.cpp \ DialogFileOperation.cpp \ DateVarSet.cpp \ diff --git a/countervarset.ui b/countervarset.ui index bd7d401..ceb8b7c 100644 --- a/countervarset.ui +++ b/countervarset.ui @@ -132,7 +132,7 @@ QSpinBox::down-arrow { Qt::StrongFocus - 1 + 0 @@ -970,37 +970,7 @@ height: 25px; - QSpinBox::down-button { - width: 23px; /* 图标显示宽度 */ - height: 23px; /* 图标显示高度 */ - border: 1px solid #333333; - border-radius: 3px; - background-color: #5396C1; -} - -QSpinBox::down-arrow { - image: url(image/down_white.png); - height: 18px; - width: 18px; -} - -QSpinBox::up-button { - width: 23px; /* 图标显示宽度 */ - height: 23px; /* 图标显示高度 */ - border: 1px solid #333333; - border-radius: 3px; - background-color: #5396C1; -} - -QSpinBox::up-arrow { - image: url(image/up_white.png); - height: 18px; - width: 18px; -} - -QSpinBox { -border: 1px solid #333333; -} + 计数器2 diff --git a/scene/BarcodeEditor.cpp b/scene/BarcodeEditor.cpp index 248f681..c63780c 100644 --- a/scene/BarcodeEditor.cpp +++ b/scene/BarcodeEditor.cpp @@ -2,7 +2,41 @@ #include "ui_BarcodeEditor.h" #include "DateFormatEditor.h" #include "DateReplaceEditor.h" +#include "CounterEditor.h" #include +#include + +// 使用SysPara的相关参数构造CounterEditorVM +CounterEditorVM makeCounterVM(SysPara* sysPara, COUNTER_TYPE type, int digitalNum) +{ + CounterEditorVM vm; + if(!sysPara) + return vm; + + vm.counterType = type; + vm.digitalNum = digitalNum; + + auto& cnt1 = vm.counter1; + cnt1.startValue = sysPara->para.cnt1StartValue; + cnt1.endValue = sysPara->para.cnt1EndValue; + cnt1.repeatValue = sysPara->para.cnt1RepeateValue; + cnt1.stepValue = sysPara->para.cnt1StepValue; + cnt1.currValue = sysPara->para.cnt1CurrValue; + // cnt1CurrentValueInitDoneFlag 与 checkBoxResetCnt1CurrValue 的勾选互为反向 + cnt1.editCurrValue = !sysPara->status.cnt1CurrentValueInitDoneFlag; + cnt1.eleEyeIncEn = (sysPara->para.eleEyeClearCntInSynMode & 0x10) != 0; + + auto& cnt2 = vm.counter2; + cnt2.startValue = sysPara->para.cnt2StartValue; + cnt2.endValue = sysPara->para.cnt2EndValue; + cnt2.repeatValue = sysPara->para.cnt2RepeateValue; + cnt2.stepValue = sysPara->para.cnt2StepValue; + cnt2.currValue = sysPara->para.cnt2CurrValue; + cnt2.editCurrValue = !sysPara->status.cnt2CurrentValueInitDoneFlag; + cnt2.eleEyeIncEn = (sysPara->para.eleEyeClearCntInSynMode & 0x20) != 0; + + return vm; +} BarcodeEditor::BarcodeEditor(QWidget *parent) : QDialog(parent), @@ -12,10 +46,15 @@ BarcodeEditor::BarcodeEditor(QWidget *parent) : setWindowModality(Qt::NonModal); m_dateFormatEditor = new DateFormatEditor(); m_dateReplaceEditor = new DateReplaceEditor(); + m_counterEditor = new CounterEditor(); - m_vm = QSharedPointer::create(); - m_vm->setDateViewModel(DateItemModel::createDefaultReplaceModel()); - m_dateReplaceEditor->setDateModel(m_vm->dateViewModel()); + ui->lineEditContent->installEventFilter(this); + + m_vm.dateViewModel = DateItemModel::createDefaultReplaceModel(); + m_dateReplaceEditor->setDateModel(m_vm.dateViewModel); + + connect(&m_barcodeFormatEditor, &DlgBarcodeFormat::accepted, this, &BarcodeEditor::onBarcodeFormatConfirmed); + connect(&m_qrcodeFormatEditor, &DlgQrcodeFormat::accepted, this, &BarcodeEditor::onQrcodeFormatConfirmed); } BarcodeEditor::~BarcodeEditor() @@ -30,63 +69,50 @@ BarcodeEditor::~BarcodeEditor() ui->tabWidget->removeTab(index); } + index = ui->tabWidget->indexOf(m_counterEditor); + if(index != -1) { + ui->tabWidget->removeTab(index); + } + + ui->lineEditContent->removeEventFilter(this); + delete m_dateFormatEditor; delete m_dateReplaceEditor; + delete m_counterEditor; delete ui; } -void BarcodeEditor::bindViewModel(QSharedPointer vm) +void BarcodeEditor::bindViewModel(const BarcodeViewModel& vm) { - if(m_vm) { - m_vm->disconnect(this); - } - m_vm = vm; - if(!m_vm) { - qDebug() << "view model is empty"; - return; - } - auto dateVm = m_vm->dateViewModel(); + // 缺失的代替表用默认值补齐 + DateItemModel& dateVm = m_vm.dateViewModel; if (dateVm.dataMap.isEmpty() || dateVm.daysMap.isEmpty() || dateVm.monthsMap.isEmpty() || dateVm.yearsMap.isEmpty() || dateVm.weeksMap.isEmpty() || dateVm.hoursMap.isEmpty()) { - DateItemModel defaultReplaceModel = DateItemModel::createDefaultReplaceModel(); - if (dateVm.dataMap.isEmpty()) { - dateVm.dataMap = defaultReplaceModel.dataMap; - } - if (dateVm.daysMap.isEmpty()) { - dateVm.daysMap = defaultReplaceModel.daysMap; - } - if (dateVm.monthsMap.isEmpty()) { - dateVm.monthsMap = defaultReplaceModel.monthsMap; - } - if (dateVm.yearsMap.isEmpty()) { - dateVm.yearsMap = defaultReplaceModel.yearsMap; - } - if (dateVm.weeksMap.isEmpty()) { - dateVm.weeksMap = defaultReplaceModel.weeksMap; - } - if (dateVm.hoursMap.isEmpty()) { - dateVm.hoursMap = defaultReplaceModel.hoursMap; - } - m_vm->setDateViewModel(dateVm); + DateItemModel def = DateItemModel::createDefaultReplaceModel(); + if (dateVm.dataMap.isEmpty()) dateVm.dataMap = def.dataMap; + if (dateVm.daysMap.isEmpty()) dateVm.daysMap = def.daysMap; + if (dateVm.monthsMap.isEmpty()) dateVm.monthsMap = def.monthsMap; + if (dateVm.yearsMap.isEmpty()) dateVm.yearsMap = def.yearsMap; + if (dateVm.weeksMap.isEmpty()) dateVm.weeksMap = def.weeksMap; + if (dateVm.hoursMap.isEmpty()) dateVm.hoursMap = def.hoursMap; } DateFormatEditorVM dateFormatVM; - if(m_vm->dateViewModel().daysOffset > 0) { - dateFormatVM.expirationValue = m_vm->dateViewModel().daysOffset; + if(dateVm.daysOffset > 0) { + dateFormatVM.expirationValue = dateVm.daysOffset; dateFormatVM.expirationType = EXPIRATION_TYPE_DAY; } - else if(m_vm->dateViewModel().monthsOffset > 0) { - dateFormatVM.expirationValue = m_vm->dateViewModel().monthsOffset; + else if(dateVm.monthsOffset > 0) { + dateFormatVM.expirationValue = dateVm.monthsOffset; dateFormatVM.expirationType = EXPIRATION_TYPE_MONTH; } - - dateFormatVM.pattern = m_vm->dateViewModel().datetimePattern; + dateFormatVM.pattern = dateVm.datetimePattern; m_dateFormatEditor->setViewModel(dateFormatVM); - m_dateReplaceEditor->setDateModel(m_vm->dateViewModel()); + m_dateReplaceEditor->setDateModel(dateVm); - if(vm->contentPattern().contains("{t}")) { + if(m_vm.contentPattern.contains("{t}")) { if(ui->tabWidget->indexOf(m_dateFormatEditor) == -1) { ui->tabWidget->addTab(m_dateFormatEditor, tr(u8"日期/时间")); } @@ -109,22 +135,72 @@ void BarcodeEditor::bindViewModel(QSharedPointer vm) } } - if(vm->contentPattern().contains("{c}")) { - // TODO:: 添加计数器选项卡 + if(m_vm.contentPattern.contains("{c}")) { + if(ui->tabWidget->indexOf(m_counterEditor) == -1) { + ui->tabWidget->addTab(m_counterEditor, tr(u8"计数器")); + } + m_counterEditor->setViewModel(makeCounterVM(m_sysPara, + static_cast(m_vm.counterViewModel.counterType), + m_vm.counterViewModel.digitalNum)); + m_counterEditor->setFixedSize(ui->tabBarcode->size()); + } + else { + auto index = ui->tabWidget->indexOf(m_counterEditor); + if(index != -1) { + ui->tabWidget->removeTab(index); + } } } -QSharedPointer BarcodeEditor::viewModel() const +BarcodeViewModel BarcodeEditor::viewModel() { + // 从子编辑器拉取最新值回写到 m_vm + + if(m_vm.contentPattern.contains("{t}")) { + DateFormatEditorVM fmt = m_dateFormatEditor->viewModel(); + m_vm.dateViewModel.datetimePattern = fmt.pattern; + if(fmt.expirationType == EXPIRATION_TYPE_DAY) { + m_vm.dateViewModel.daysOffset = fmt.expirationValue; + m_vm.dateViewModel.monthsOffset = 0; + } + else if(fmt.expirationType == EXPIRATION_TYPE_MONTH) { + m_vm.dateViewModel.monthsOffset = fmt.expirationValue; + m_vm.dateViewModel.daysOffset = 0; + } + else { + m_vm.dateViewModel.daysOffset = 0; + m_vm.dateViewModel.monthsOffset = 0; + } + + // 代替表从 DateReplaceEditor 取 + DateItemModel rep = m_dateReplaceEditor->dateModel(); + m_vm.dateViewModel.dataMap = rep.dataMap; + m_vm.dateViewModel.daysMap = rep.daysMap; + m_vm.dateViewModel.monthsMap = rep.monthsMap; + m_vm.dateViewModel.yearsMap = rep.yearsMap; + m_vm.dateViewModel.weeksMap = rep.weeksMap; + m_vm.dateViewModel.hoursMap = rep.hoursMap; + } + + if(m_vm.contentPattern.contains("{c}")) { + CounterEditorVM cnt = m_counterEditor->viewModel(); + m_vm.counterViewModel.counterType = cnt.counterType; + m_vm.counterViewModel.digitalNum = cnt.digitalNum; + } + return m_vm; } void BarcodeEditor::onBtnFormatClicked() { - if(!m_vm) - return; - - // 显示对话框,用于针对于条形码、二维码的格式调整,例如二维码的编码类型、大小、条形码的宽度、等等 + if(m_vm.type == BARCODE_TYPE_BARCODE) { + m_barcodeFormatEditor.setViewModel(m_vm.format.value()); + m_barcodeFormatEditor.show(); + } + else { + m_qrcodeFormatEditor.setViewModel(m_vm.format.value()); + m_qrcodeFormatEditor.show(); + } } void BarcodeEditor::onBtnDatetimeClicked() @@ -140,19 +216,75 @@ void BarcodeEditor::onBtnDatetimeClicked() void BarcodeEditor::onBtnCounterClicked() { - if(ui->lineEditContent->text().contains("{c}")) { + QString cntStr = "{c}"; + if(ui->lineEditContent->text().contains(cntStr)) { qInfo() << "Cannot add counter format twice"; return; } - ui->lineEditContent->insert("{c}"); + ui->lineEditContent->insert(cntStr); } -void BarcodeEditor::onContentChanged(QString content) +void BarcodeEditor::onCheckBtnClicked() { - if(!m_vm) - return; + m_vm = viewModel(); + emit accepted(); +} +void BarcodeEditor::onCloseBtnClicked() +{ + emit rejected(); +} + +void BarcodeEditor::onBarcodeFormatConfirmed() +{ + m_vm.format.setValue(m_barcodeFormatEditor.viewModel()); + m_vm.type = BARCODE_TYPE_BARCODE; + + auto b = ui->cbBoxType->blockSignals(true); + ui->cbBoxType->setCurrentIndex(int(m_vm.type)); + ui->cbBoxType->blockSignals(b); +} + +void BarcodeEditor::onQrcodeFormatConfirmed() +{ + m_vm.format.setValue(m_qrcodeFormatEditor.viewModel()); + m_vm.type = BARCODE_TYPE_QRCODE; + + auto b = ui->cbBoxType->blockSignals(true); + ui->cbBoxType->setCurrentIndex(int(m_vm.type)); + ui->cbBoxType->blockSignals(b); +} + +bool BarcodeEditor::eventFilter(QObject *obj, QEvent *event) +{ + if(obj == ui->lineEditContent) { + if(event->type() == QEvent::KeyPress) { + QKeyEvent* keyEvent = static_cast(event); + if(keyEvent->key() == Qt::Key_Backspace) { + QString text = ui->lineEditContent->text(); + int cursor = ui->lineEditContent->cursorPosition(); + if(cursor < 0) { + return false; + } + + // 碰到 {t} 或 {c},直接删除 + QString varText = text.mid(cursor - 3, 3); + if(varText == "{t}" || varText == "{c}") { + ui->lineEditContent->setText(text.remove(cursor - 3, 3)); + } + } + } + } + + return false; +} + +void BarcodeEditor::onContentChanged(QString content) +{ + const DateItemModel& dateVm = m_vm.dateViewModel; + + // 根据内容决定是否显示日期/时间选项卡 if(!content.contains("{t}")) { auto index = ui->tabWidget->indexOf(m_dateFormatEditor); if(index != -1) { @@ -176,20 +308,37 @@ void BarcodeEditor::onContentChanged(QString content) m_dateReplaceEditor->setFixedSize(ui->tabBarcode->size()); DateFormatEditorVM dateFormatVM; - if(m_vm->dateViewModel().daysOffset > 0) { - dateFormatVM.expirationValue = m_vm->dateViewModel().daysOffset; + if(dateVm.daysOffset > 0) { + dateFormatVM.expirationValue = dateVm.daysOffset; dateFormatVM.expirationType = EXPIRATION_TYPE_DAY; } - else if(m_vm->dateViewModel().monthsOffset > 0) { - dateFormatVM.expirationValue = m_vm->dateViewModel().monthsOffset; + else if(dateVm.monthsOffset > 0) { + dateFormatVM.expirationValue = dateVm.monthsOffset; dateFormatVM.expirationType = EXPIRATION_TYPE_MONTH; } - dateFormatVM.pattern = m_vm->dateViewModel().datetimePattern; + dateFormatVM.pattern = dateVm.datetimePattern; m_dateFormatEditor->setViewModel(dateFormatVM); - - m_dateReplaceEditor->setDateModel(m_vm->dateViewModel()); + + m_dateReplaceEditor->setDateModel(dateVm); } - m_vm->setContentPattern(content); + // 根据内容决定是否显示计数器选项卡 + if(!content.contains("{c}")) { + auto index = ui->tabWidget->indexOf(m_counterEditor); + if(index != -1) { + ui->tabWidget->removeTab(index); + } + } + else { + if(ui->tabWidget->indexOf(m_counterEditor) == -1) { + ui->tabWidget->addTab(m_counterEditor, tr(u8"计数器")); + m_counterEditor->setViewModel(makeCounterVM(m_sysPara, + static_cast(m_vm.counterViewModel.counterType), + m_vm.counterViewModel.digitalNum)); + } + m_counterEditor->setFixedSize(ui->tabBarcode->size()); + } + + m_vm.contentPattern = content; } diff --git a/scene/BarcodeEditor.h b/scene/BarcodeEditor.h index 19c51d3..533f549 100644 --- a/scene/BarcodeEditor.h +++ b/scene/BarcodeEditor.h @@ -4,9 +4,35 @@ #include #include "ViewModels.h" +#include "SysPara.h" +#include "dlgQrcodeFormat.h" +#include "DlgBarcodeFormat.h" +#include class DateFormatEditor; class DateReplaceEditor; +class CounterEditor; + +enum BarcodeType { + BARCODE_TYPE_BARCODE, + BARCODE_TYPE_QRCODE, +}; + +/** + * @brief 条码设置界面所用的视图模型 + * + * @remark contentPattern 内可包含变量,如 {t} 表示日期/时间、{c} 表示计数器。 + * 仅当 contentPattern 含有相应变量时,counterViewModel / dateViewModel 字段才有意义。 + */ +struct BarcodeViewModel { + QString contentPattern; // 条形码内容模版,例如 "ABC{t}{c1}" + CounterViewModel counterViewModel; // 计数器视图模型 + DateItemModel dateViewModel; // 日期视图模型 + BarcodeType type = BARCODE_TYPE_BARCODE; + QVariant format; +}; + +Q_DECLARE_METATYPE(BarcodeViewModel); namespace Ui { class BarcodeEditor; @@ -20,9 +46,34 @@ public: explicit BarcodeEditor(QWidget *parent = nullptr); ~BarcodeEditor(); - void bindViewModel(QSharedPointer vm); + /** + * @brief 绑定系统参数 + * + * 计数器配置选项卡所需的各个计数器的配置通过此方式提供; + * @note + * BarcodeEditor 将在 @see bindViewModel 中读取 sysPara->para.cnt1*** 或 sysPara->para.cnt2*** 相关参数,并在用户点击确认按钮时修改它们。 + * + * @remark 沿用的是旧逻辑 + * + * @param sysPara + */ + void bindSysPara(SysPara* sysPara) { m_sysPara = sysPara; } - QSharedPointer viewModel() const; + /** + * @brief 注入条形码视图模型(纯结构体,按值拷贝) + * + * @param vm + */ + void bindViewModel(const BarcodeViewModel& vm); + + /** + * @brief 获取当前视图模型 + * + * @note 调用前会先从各子编辑器收集最新值回写到内部 m_vm,再返回。 + * + * @return BarcodeViewModel + */ + BarcodeViewModel viewModel(); private slots: @@ -51,13 +102,46 @@ private slots: */ void onBtnCounterClicked(); + /** + * @brief 确定按钮点击时触发 + * + */ + void onCheckBtnClicked(); + + /** + * @brief 取消按钮点击时触发 + * + */ + void onCloseBtnClicked(); + + /** + * @brief 条形码格式确认时触发 + * + */ + void onBarcodeFormatConfirmed(); + + /** + * @brief 二维码格式确认时触发 + * + */ + void onQrcodeFormatConfirmed(); + +protected: + virtual bool eventFilter(QObject* obj, QEvent* event) override; + private: Ui::BarcodeEditor *ui; - QSharedPointer m_vm; + BarcodeViewModel m_vm; DateFormatEditor *m_dateFormatEditor = nullptr; DateReplaceEditor *m_dateReplaceEditor = nullptr; + CounterEditor *m_counterEditor = nullptr; + + SysPara* m_sysPara = nullptr; + + DlgBarcodeFormat m_barcodeFormatEditor; + DlgQrcodeFormat m_qrcodeFormatEditor; }; #endif // BARCODEEDITOR_H diff --git a/scene/BarcodeEditor.ui b/scene/BarcodeEditor.ui index 93a36ba..a7d3e5b 100644 --- a/scene/BarcodeEditor.ui +++ b/scene/BarcodeEditor.ui @@ -271,7 +271,7 @@ QSpinBox::down-arrow { 日期 - + 60 @@ -323,38 +323,6 @@ QSpinBox::down-arrow { - - closeBtn - clicked() - BarcodeEditor - reject() - - - 691 - 562 - - - 718 - 684 - - - - - checkBtn - clicked() - BarcodeEditor - accept() - - - 573 - 563 - - - 541 - 671 - - - lineEditContent textChanged(QString) @@ -378,7 +346,7 @@ QSpinBox::down-arrow { onBtnFormatClicked() - 518 + 412 231 @@ -395,7 +363,7 @@ QSpinBox::down-arrow { 562 - 325 + 255 915 @@ -404,14 +372,14 @@ QSpinBox::down-arrow { - btnCounter + btnCounter1 clicked() BarcodeEditor onBtnCounterClicked() 553 - 370 + 300 819 @@ -419,11 +387,45 @@ QSpinBox::down-arrow { + + checkBtn + clicked() + BarcodeEditor + onCheckBtnClicked() + + + 543 + 558 + + + 581 + 705 + + + + + closeBtn + clicked() + BarcodeEditor + onCloseBtnClicked() + + + 689 + 561 + + + 708 + 734 + + + onContentChanged(QString) onBtnFormatClicked() onBtnDatetimeClicked() onBtnCounterClicked() + onCheckBtnClicked() + onCloseBtnClicked() diff --git a/scene/CounterEditor.cpp b/scene/CounterEditor.cpp new file mode 100644 index 0000000..01fe2a4 --- /dev/null +++ b/scene/CounterEditor.cpp @@ -0,0 +1,138 @@ +#include "CounterEditor.h" +#include "ui_CounterEditor.h" +#include "ViewModels.h" + +CounterEditor::CounterEditor(QWidget *parent) : + QWidget(parent), + ui(new Ui::CounterEditor) +{ + ui->setupUi(this); + + connect(ui->checkBoxResetCnt2CurrValue, &QCheckBox::toggled, + this, &CounterEditor::onEditCurrValueToggled); + + connect(ui->cbBoxCounterType, QOverload::of(&QComboBox::currentIndexChanged), this, &CounterEditor::onCounterTypeChanged); + connect(ui->cbBoxDigitalNum, QOverload::of(&QComboBox::currentIndexChanged), this, &CounterEditor::onDigitalNumChanged); + + connect(ui->spinBoxCnt2StartValue, QOverload::of(&QSpinBox::valueChanged), this, [this](int) {fetchCounterConfigFromView();} ); + connect(ui->spinBoxCnt2EndValue, QOverload::of(&QSpinBox::valueChanged), this, [this](int) {fetchCounterConfigFromView();} ); + connect(ui->spinBoxCnt2RepeateCnt, QOverload::of(&QSpinBox::valueChanged), this, [this](int) {fetchCounterConfigFromView();} ); + connect(ui->spinBoxCnt2StepValue, QOverload::of(&QSpinBox::valueChanged), this, [this](int) {fetchCounterConfigFromView();} ); + connect(ui->spinBoxCnt2CurrValue, QOverload::of(&QSpinBox::valueChanged), this, [this](int) {fetchCounterConfigFromView();} ); + + connect(ui->checkBoxResetCnt2CurrValue, &QCheckBox::clicked, this, [this](bool) {fetchCounterConfigFromView();} ); + connect(ui->eleCNT2IncEn, &QCheckBox::clicked, this, [this](bool) {fetchCounterConfigFromView();} ); + + setViewModel(m_vm); +} + +CounterEditor::~CounterEditor() +{ + delete ui; +} + +/** + * @brief 设置视图模型并将其更新至UI + * + * @param vm + */ +void CounterEditor::setViewModel(CounterEditorVM vm) +{ + m_vm = std::move(vm); + + // 根据 VM 中的当前计数器ID 确定显示哪个计数器的配置 + CounterEditorVM::CounterSlot& cnt = m_vm.counterType == COUNTER_TYPE_1 ? m_vm.counter1 : m_vm.counter2; + + auto b = ui->spinBoxCnt2StartValue->blockSignals(true); + ui->spinBoxCnt2StartValue->setValue(cnt.startValue); + ui->spinBoxCnt2StartValue->blockSignals(b); + + b = ui->spinBoxCnt2EndValue->blockSignals(true); + ui->spinBoxCnt2EndValue->setValue(cnt.endValue); + ui->spinBoxCnt2EndValue->blockSignals(b); + + b = ui->spinBoxCnt2RepeateCnt->blockSignals(true); + ui->spinBoxCnt2RepeateCnt->setValue(cnt.repeatValue); + ui->spinBoxCnt2RepeateCnt->blockSignals(b); + + b = ui->spinBoxCnt2StepValue->blockSignals(true); + ui->spinBoxCnt2StepValue->setValue(cnt.stepValue); + ui->spinBoxCnt2StepValue->blockSignals(b); + + b = ui->spinBoxCnt2CurrValue->blockSignals(true); + ui->spinBoxCnt2CurrValue->setValue(cnt.currValue); + ui->spinBoxCnt2CurrValue->blockSignals(b); + + b = ui->checkBoxResetCnt2CurrValue->blockSignals(true); + ui->checkBoxResetCnt2CurrValue->setChecked(cnt.editCurrValue); + ui->checkBoxResetCnt2CurrValue->blockSignals(b); + + b = ui->eleCNT2IncEn->blockSignals(true); + ui->eleCNT2IncEn->setChecked(cnt.eleEyeIncEn); + ui->eleCNT2IncEn->blockSignals(b); + + ui->spinBoxCnt2CurrValue->setEnabled(cnt.editCurrValue); + ui->labelCnt2CurrValue->setText(QString::number(cnt.currValue)); + + b = ui->cbBoxCounterType->blockSignals(true); + ui->cbBoxCounterType->setCurrentIndex(m_vm.counterType == COUNTER_TYPE_1 ? 0 : 1); + ui->cbBoxCounterType->blockSignals(b); + + b = ui->cbBoxDigitalNum->blockSignals(true); + ui->cbBoxDigitalNum->setCurrentIndex(m_vm.digitalNum - 1); + ui->cbBoxDigitalNum->blockSignals(b); +} + +/** + * @brief 从界面获取最新配置以刷新视图模型 + * + * @return CounterEditorVM 最新的视图模型 + */ +CounterEditorVM CounterEditor::viewModel() +{ + m_vm.counterType = ui->cbBoxCounterType->currentIndex() == 0 ? COUNTER_TYPE_1 : COUNTER_TYPE_2; + m_vm.digitalNum = ui->cbBoxDigitalNum->currentIndex() + 1; + fetchCounterConfigFromView(); + return m_vm; +} + +void CounterEditor::onCounterTypeChanged(int i) +{ + i = std::max(i, 0); + m_vm.counterType = i == 0 ? COUNTER_TYPE_1 : COUNTER_TYPE_2; + setViewModel(m_vm); +} + +void CounterEditor::onDigitalNumChanged(int i) +{ + i = std::max(i, 0); + m_vm.digitalNum = i + 1; +} + +/** + * @brief 从界面拉取计数器配置 + * + * 根据当前所选的计数器ID更新对应的计数器配置 + * + */ +void CounterEditor::fetchCounterConfigFromView() +{ + CounterEditorVM::CounterSlot& cnt = m_vm.counterType == COUNTER_TYPE_1 ? m_vm.counter1 : m_vm.counter2; + + cnt.startValue = ui->spinBoxCnt2StartValue->value(); + cnt.endValue = ui->spinBoxCnt2EndValue->value(); + cnt.repeatValue = ui->spinBoxCnt2RepeateCnt->value(); + cnt.stepValue = ui->spinBoxCnt2StepValue->value(); + cnt.currValue = ui->spinBoxCnt2CurrValue->value(); + cnt.editCurrValue = ui->checkBoxResetCnt2CurrValue->isChecked(); + cnt.eleEyeIncEn = ui->eleCNT2IncEn->isChecked(); +} + +/** + * @brief 简单启用对应SpinBox + * + */ +void CounterEditor::onEditCurrValueToggled() +{ + ui->spinBoxCnt2CurrValue->setEnabled(ui->checkBoxResetCnt2CurrValue->isChecked()); +} \ No newline at end of file diff --git a/scene/CounterEditor.h b/scene/CounterEditor.h new file mode 100644 index 0000000..96bd50a --- /dev/null +++ b/scene/CounterEditor.h @@ -0,0 +1,69 @@ +#ifndef COUNTEREDITOR_H +#define COUNTEREDITOR_H + +#include + +namespace Ui { +class CounterEditor; +} + +/** + * @brief 用于 CounterEditor 的视图模型 + * + * 包含了计数器ID、计数器位数以及各个计数器当前的配置 + * + */ +struct CounterEditorVM { + + int counterType = 7; + int digitalNum = 2; + + struct CounterSlot { + int startValue = 1; + int endValue = 9999; + int repeatValue = 1; + int stepValue = 1; + int currValue = 1; + bool editCurrValue = false; // 对应 checkBoxResetCnt2CurrValue:勾选才允许重置/编辑当前值 + bool eleEyeIncEn = false; // 对应 eleCNT2IncEn:电眼触发使计数器+1 + }; + + CounterSlot counter1, counter2; +}; + +class CounterEditor : public QWidget +{ + Q_OBJECT + +public: + explicit CounterEditor(QWidget *parent = nullptr); + ~CounterEditor(); + + /** + * @brief 设置 UI 所用的视图模型 + * + * @param vm + */ + void setViewModel(CounterEditorVM vm); + + /** + * @brief 获取 UI 当前的视图模型 + * + * @return CounterEditorVM + */ + CounterEditorVM viewModel(); + +private slots: + void onEditCurrValueToggled(); + void onCounterTypeChanged(int i); + void onDigitalNumChanged(int i); + +private: + void fetchCounterConfigFromView(); + + Ui::CounterEditor *ui; + + CounterEditorVM m_vm; +}; + +#endif // COUNTEREDITOR_H diff --git a/scene/CounterEditor.ui b/scene/CounterEditor.ui new file mode 100644 index 0000000..8a21143 --- /dev/null +++ b/scene/CounterEditor.ui @@ -0,0 +1,603 @@ + + + CounterEditor + + + + 0 + 0 + 732 + 522 + + + + QWidget { + font-size: 16px; +} + + + + + 369 + 122 + 100 + 50 + + + + + 0 + 0 + + + + + 100 + 50 + + + + + 100 + 50 + + + + + + + 9999999 + + + 9999 + + + + + + 475 + 122 + 100 + 50 + + + + + 0 + 0 + + + + + 100 + 50 + + + + + 100 + 50 + + + + Qt::LeftToRight + + + 重复数: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 581 + 122 + 100 + 50 + + + + + 0 + 0 + + + + + 100 + 50 + + + + + 100 + 50 + + + + 1 + + + 65535 + + + + + + 157 + 179 + 100 + 50 + + + + + 0 + 0 + + + + + 100 + 50 + + + + + 100 + 50 + + + + -49999999 + + + 49999999 + + + 1 + + + + + true + + + + 475 + 179 + 100 + 50 + + + + + 0 + 0 + + + + + 100 + 50 + + + + + 100 + 50 + + + + + -1 + + + + Qt::LeftToRight + + + + + + Qt::AlignCenter + + + + + + 51 + 122 + 100 + 50 + + + + + 0 + 0 + + + + + 100 + 50 + + + + + 100 + 50 + + + + Qt::LeftToRight + + + 起始值: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 157 + 122 + 100 + 50 + + + + + 0 + 0 + + + + + 100 + 50 + + + + + 100 + 50 + + + + 999999 + + + 1 + + + + + + 263 + 122 + 100 + 50 + + + + + 0 + 0 + + + + + 100 + 50 + + + + + 100 + 50 + + + + Qt::LeftToRight + + + 结束值: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + false + + + + 369 + 179 + 100 + 50 + + + + + 0 + 0 + + + + + 100 + 50 + + + + + 100 + 50 + + + + 0 + + + 999999999 + + + 1 + + + + + + 270 + 179 + 100 + 50 + + + + + 100 + 50 + + + + + 100 + 50 + + + + + 1 + + + 1 + + + 1 + + + 1 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 100 + 50 + + + + QRadioButton::indicator { +width: 25px; +height: 25px; +} + + + 当前值: + + + + + + + + + 56 + 179 + 100 + 50 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 100 + 50 + + + + QRadioButton::indicator { +width: 25px; +height: 25px; +} + + + 增量值: + + + + + + + + + 70 + 60 + 81 + 31 + + + + 计数器ID: + + + + + + 160 + 60 + 121 + 31 + + + + + 计数器1 + + + + + 计数器2 + + + + + + + 370 + 60 + 91 + 31 + + + + 计数器位数: + + + + + + 470 + 60 + 101 + 31 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + + + diff --git a/scene/DlgBarcodeFormat.cpp b/scene/DlgBarcodeFormat.cpp new file mode 100644 index 0000000..175f9c6 --- /dev/null +++ b/scene/DlgBarcodeFormat.cpp @@ -0,0 +1,51 @@ +#include "DlgBarcodeFormat.h" +#include "ui_DlgBarcodeFormat.h" + +DlgBarcodeFormat::DlgBarcodeFormat(QWidget *parent) : + QDialog(parent), + ui(new Ui::DlgBarcodeFormat) +{ + ui->setupUi(this); + + ui->BarCodeType->addItem("BARCODE_128"); + ui->BarCodeType->addItem("BARCODE_93"); + ui->BarCodeType->addItem("BARCODE_ISBN"); + ui->BarCodeType->addItem("BARCODE_EAN"); + ui->BarCodeType->addItem("BARCODE_UPC"); + ui->BarCodeType->addItem("BARCODE_39"); + + ui->BarCodeHeigh->addItem(tr("5点")); + ui->BarCodeHeigh->addItem(tr("7点")); + ui->BarCodeHeigh->addItem(tr("9点")); + ui->BarCodeHeigh->addItem(tr("12点")); + ui->BarCodeHeigh->addItem(tr("16点")); + ui->BarCodeHeigh->addItem(tr("24点")); + + ui->BarCodeHeigh->setCurrentIndex(2); + ui->BarCodeType->setCurrentIndex(0); +} + +DlgBarcodeFormat::~DlgBarcodeFormat() +{ + delete ui; +} + +void DlgBarcodeFormat::setViewModel(DlgBarcodeFormatVM vm) +{ + m_vm = vm; + ui->BarCodeType->setCurrentText(vm.type); + ui->BarCodeHeigh->setCurrentText(tr("%1点").arg(vm.height)); + ui->BarCodeDot->setCurrentText(tr("%1点").arg(vm.width)); + ui->BarCodeScale->setValue(vm.scale); + ui->checkBoxAddText->setChecked(vm.txtVisible); +} + +DlgBarcodeFormatVM DlgBarcodeFormat::viewModel() +{ + m_vm.type = ui->BarCodeType->currentText(); + m_vm.height = ui->BarCodeHeigh->currentText().remove(tr("点")).toInt(); + m_vm.width = ui->BarCodeDot->currentText().remove(tr("点")).toInt(); + m_vm.scale = ui->BarCodeScale->value(); + m_vm.txtVisible = ui->checkBoxAddText->isChecked(); + return m_vm; +} diff --git a/scene/DlgBarcodeFormat.h b/scene/DlgBarcodeFormat.h new file mode 100644 index 0000000..2862fe1 --- /dev/null +++ b/scene/DlgBarcodeFormat.h @@ -0,0 +1,40 @@ +#ifndef DLGBARCODEFORMAT_H +#define DLGBARCODEFORMAT_H + +#include +#include "ViewModels.h" + +namespace Ui { +class DlgBarcodeFormat; +} + +struct DlgBarcodeFormatVM { + QString type = "BARCODE_128"; + int height = 9; + int width = 1; + int scale = 1; + InkType inkType = INK_TYPE_BLACK; + bool txtVisible = false; +}; + +Q_DECLARE_METATYPE(DlgBarcodeFormatVM); + +class DlgBarcodeFormat : public QDialog +{ + Q_OBJECT + +public: + explicit DlgBarcodeFormat(QWidget *parent = nullptr); + ~DlgBarcodeFormat(); + + void setViewModel(DlgBarcodeFormatVM vm); + + DlgBarcodeFormatVM viewModel(); + +private: + Ui::DlgBarcodeFormat *ui; + + DlgBarcodeFormatVM m_vm; +}; + +#endif // DLGBARCODEFORMAT_H diff --git a/scene/DlgBarcodeFormat.ui b/scene/DlgBarcodeFormat.ui new file mode 100644 index 0000000..2b6f339 --- /dev/null +++ b/scene/DlgBarcodeFormat.ui @@ -0,0 +1,288 @@ + + + DlgBarcodeFormat + + + + 0 + 0 + 510 + 380 + + + + + 0 + 0 + + + + Dialog + + + QWidget{ + font-size: 16px; +} + + + + + 300 + 150 + 60 + 31 + + + + + 60 + 16777215 + + + + false + + + false + + + 1 + + + 10 + + + 1 + + + + + + 70 + 120 + 91 + 23 + + + + 条形码高度 + + + + + + 190 + 150 + 71 + 31 + + + + + 1点 + + + + + 2点 + + + + + 3点 + + + + + 4点 + + + + + 5点 + + + + + 6点 + + + + + + + 330 + 240 + 83 + 16 + + + + + 0 + 0 + + + + + 0 + 0 + + + + 增加数字行 + + + + + + 70 + 150 + 71 + 31 + + + + + + + 300 + 70 + 81 + 31 + + + + 1 + + + + 黑墨 + + + + + 白墨 + + + + + + + 190 + 120 + 76 + 23 + + + + 条码宽度 + + + + + + 70 + 40 + 140 + 23 + + + + 条形码类型 + + + + + + 70 + 70 + 140 + 31 + + + + + 0 + 0 + + + + + 140 + 0 + + + + + + + 300 + 40 + 76 + 23 + + + + 墨水类型 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 300 + 120 + 129 + 23 + + + + 显示缩放 + + + + + + 370 + 300 + 101 + 50 + + + + ✓ + + + + + BarCodeType + comboBoxInkColor + BarCodeHeigh + BarCodeDot + BarCodeScale + checkBoxAddText + checkBtn + + + + + checkBtn + clicked() + DlgBarcodeFormat + accept() + + + 412 + 323 + + + 417 + 379 + + + + + diff --git a/scene/DlgQrcodeFormat.cpp b/scene/DlgQrcodeFormat.cpp index c5e0cb3..e4b531a 100644 --- a/scene/DlgQrcodeFormat.cpp +++ b/scene/DlgQrcodeFormat.cpp @@ -1,14 +1,32 @@ -#include "DlgQrcodeFormat.h" -#include "ui_DlgQrcodeFormat.h" - -DlgQrcodeFormat::DlgQrcodeFormat(QWidget *parent) : - QDialog(parent), - ui(new Ui::DlgQrcodeFormat) -{ - ui->setupUi(this); -} - -DlgQrcodeFormat::~DlgQrcodeFormat() -{ - delete ui; -} +#include "DlgQrcodeFormat.h" +#include "ui_DlgQrcodeFormat.h" + +DlgQrcodeFormat::DlgQrcodeFormat(QWidget *parent) : + QDialog(parent), + ui(new Ui::DlgQrcodeFormat) +{ + ui->setupUi(this); +} + +DlgQrcodeFormat::~DlgQrcodeFormat() +{ + delete ui; +} + +void DlgQrcodeFormat::setViewModel(DlgQrcodeFormatVM vm) +{ + m_vm = vm; + ui->comboBoxType->setCurrentIndex(int(vm.type)); + ui->comboBoxInkColor->setCurrentIndex(int(vm.inkType)); + ui->comboBox_DMType->setCurrentIndex(int(vm.size)); + ui->comboBox_QRCodeLevel->setCurrentIndex(int(vm.level)); +} + +DlgQrcodeFormatVM DlgQrcodeFormat::viewModel() +{ + m_vm.type = QRCodeType(ui->comboBoxType->currentIndex()); + m_vm.inkType = InkType(ui->comboBoxInkColor->currentIndex()); + m_vm.level = QRCodeLevel(ui->comboBox_QRCodeLevel->currentIndex()); + m_vm.size = QRCodeSize(ui->comboBox_DMType->currentIndex()); + return m_vm; +} diff --git a/scene/DlgQrcodeFormat.h b/scene/DlgQrcodeFormat.h index a5be5b9..c028f22 100644 --- a/scene/DlgQrcodeFormat.h +++ b/scene/DlgQrcodeFormat.h @@ -1,22 +1,60 @@ -#ifndef DLGQRCODEFORMAT_H -#define DLGQRCODEFORMAT_H - -#include - -namespace Ui { -class DlgQrcodeFormat; -} - -class DlgQrcodeFormat : public QDialog -{ - Q_OBJECT - -public: - explicit DlgQrcodeFormat(QWidget *parent = nullptr); - ~DlgQrcodeFormat(); - -private: - Ui::DlgQrcodeFormat *ui; -}; - -#endif // DLGQRCODEFORMAT_H +#ifndef DLGQRCODEFORMAT_H +#define DLGQRCODEFORMAT_H + +#include +#include "ViewModels.h" + +namespace Ui { +class DlgQrcodeFormat; +} + +enum QRCodeType { + QR_CODE_TYPE_DATA_MATRIX = 0, + QR_CODE_TYPE_QRCODE = 1, +}; + +enum QRCodeLevel { + QR_CODE_LEVEL_L = 0, + QR_CODE_LEVEL_M = 1, + QR_CODE_LEVEL_H = 2, + QR_CODE_LEVEL_Q = 3, +}; + +enum QRCodeSize { + QR_CODE_SIZE_DEFAULT, + QR_CODE_SIZE_8X18, + QR_CODE_SIZE_8X32, + QR_CODE_SIZE_12X26, + QR_CODE_SIZE_12X36, + QR_CODE_SIZE_16X36, + QR_CODE_SIZE_16X48, +}; + +struct DlgQrcodeFormatVM { + QRCodeType type = QR_CODE_TYPE_DATA_MATRIX; + QRCodeLevel level = QR_CODE_LEVEL_L; + QRCodeSize size = QR_CODE_SIZE_DEFAULT; + InkType inkType = INK_TYPE_BLACK; +}; + +Q_DECLARE_METATYPE(DlgQrcodeFormatVM); + +class DlgQrcodeFormat : public QDialog +{ + Q_OBJECT + +public: + explicit DlgQrcodeFormat(QWidget *parent = nullptr); + ~DlgQrcodeFormat(); + + void setViewModel(DlgQrcodeFormatVM vm); + + DlgQrcodeFormatVM viewModel(); + +private: + Ui::DlgQrcodeFormat *ui; + + DlgQrcodeFormatVM m_vm; +}; + +#endif // DLGQRCODEFORMAT_H diff --git a/scene/DlgQrcodeFormat.ui b/scene/DlgQrcodeFormat.ui index a12c959..6029389 100644 --- a/scene/DlgQrcodeFormat.ui +++ b/scene/DlgQrcodeFormat.ui @@ -1,18 +1,229 @@ - - DlgQrcodeFormat - - - - 0 - 0 - 400 - 300 - - - - Dialog - - - - - + + + DlgQrcodeFormat + + + + 0 + 0 + 510 + 380 + + + + + 0 + 0 + + + + Dialog + + + QWidget{ + font-size: 16px; +} + + + + + 40 + 60 + 251 + 31 + + + + + DataMatrix + + + + + QRCode + + + + + + + 40 + 130 + 251 + 31 + + + + + 正相打印 + + + + + 反相打印 + + + + + + + 40 + 180 + 141 + 21 + + + + DM码尺寸: + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + 40 + 210 + 157 + 31 + + + + + 0 + 0 + + + + + 默认 + + + + + 8 x 18 + + + + + 8 x 32 + + + + + 12 x 26 + + + + + 12 x 36 + + + + + 16 x 36 + + + + + 16 x 48 + + + + + + + 210 + 210 + 156 + 31 + + + + + 低级 + + + + + 中级 + + + + + 高级 + + + + + 超高级 + + + + + + + 40 + 21 + 181 + 31 + + + + 类型 + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + 40 + 101 + 141 + 21 + + + + 墨水类型 + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + 370 + 300 + 101 + 50 + + + + ✓ + + + + + + + checkBtn + clicked() + DlgQrcodeFormat + accept() + + + 423 + 327 + + + 463 + 504 + + + + + diff --git a/scene/ItemCommon.cpp b/scene/ItemCommon.cpp new file mode 100644 index 0000000..0769bc4 --- /dev/null +++ b/scene/ItemCommon.cpp @@ -0,0 +1,98 @@ +#include "ItemCommon.h" + +QString generateTxtFromDateItemModel(const DateItemModel &model, const QDateTime &time) +{ + QString result = model.datetimePattern; + + // 应用偏移量 + QDateTime applyDateTime = time; + if(model.monthsOffset != 0) { + applyDateTime = time.addMonths(model.monthsOffset); + } + else if(model.daysOffset != 0) { + applyDateTime = time.addDays(model.daysOffset); + } + + // 使用正则表达式匹配并替换各种格式化模式 + + // 匹配四位数年份 yyyy + int i = result.indexOf("yyyy"); + if(i != -1) { + int year = applyDateTime.date().year(); + QString yearStr = model.yearsMap.contains(year) ? model.yearsMap[year] : QString::number(year); + result.replace(i, 4, yearStr); + } + + // 匹配两位数年份 yy + i = result.indexOf("YY"); + if(i != -1) { + QString yearStr = QString::number(applyDateTime.date().year()).right(2); + result.replace(i, 2, yearStr); + } + + // 匹配两位数月份 MM + i = result.indexOf("MM"); + if(i != -1) { + result.replace(i, 2, model.monthsMap[applyDateTime.date().month() - 1]); + } + + // 匹配两位数日期 dd + i = result.indexOf("dd"); + if(i != -1) { + result.replace(i, 2, model.daysMap[applyDateTime.date().day() - 1]); + } + + // 匹配两位数小时 HH + i = result.indexOf("HH"); + if(i != -1) { + result.replace(i, 2, model.hoursMap[applyDateTime.time().hour()]); + } + + // 匹配两位数分钟 mm + QRegExp minutePattern("mm"); + if (result.contains(minutePattern)) { + int minute = applyDateTime.time().minute(); + result.replace(minutePattern, QString::number(minute).rightJustified(2, '0')); + } + + // 匹配两位数秒钟 ss + QRegExp secondPattern("ss"); + if (result.contains(secondPattern)) { + int second = applyDateTime.time().second(); + result.replace(secondPattern, QString::number(second).rightJustified(2, '0')); + } + + // 格式化周几 w + i = result.indexOf("w"); + if (i != -1) { + result.replace(i, 1, model.weeksMap[applyDateTime.date().dayOfWeek() - 1]); + } + + // 格式化年中周数 c + QRegExp weekNumberPattern("c"); + if (result.contains(weekNumberPattern)) { + result.replace(weekNumberPattern, QString::number(applyDateTime.date().weekNumber())); + } + + return result; +} + + +QString generateTxtFromBarcodeViewModel(const BarcodeViewModel &vm, const std::array counterValues, const QDateTime &time) +{ + QString txt = vm.contentPattern; + auto pos = vm.contentPattern.indexOf("{t}"); + if(pos != -1) { + txt.replace(pos, 3, generateTxtFromDateItemModel(vm.dateViewModel, time)); + } + + pos = vm.contentPattern.indexOf("{c}"); + if(pos != 1) { + auto cntValue = vm.counterViewModel.counterType == COUNTER_TYPE_1 ? counterValues[0] : counterValues[1]; + auto valueStr = QString("%1").arg(cntValue, 10, QChar('0'));; + valueStr.right(vm.counterViewModel.digitalNum); + txt.replace(pos, 3, valueStr); + } + + return txt; +} \ No newline at end of file diff --git a/scene/ItemCommon.h b/scene/ItemCommon.h new file mode 100644 index 0000000..2978f71 --- /dev/null +++ b/scene/ItemCommon.h @@ -0,0 +1,31 @@ +#ifndef _ITEM_COMMON_H_ +#define _ITEM_COMMON_H_ + +#include "ViewModels.h" +#include +#include +#include +#include "BarcodeEditor.h" + +QString generateTxtFromDateItemModel(const DateItemModel& model, const QDateTime& time); + +/** + * @brief 根据条形码视图模型的内容模版生成字符串, + * 生成的字符串可用于创建条形码或二维码 + * + * @example + * input: "ABC_{c}_{t}" + * output: "ABC_1230_2026/04/30" + * + * @remark + * 函数根据vm中的 contentPattern 是否存在变量模版,如果存在计数器变量,则使用 counterViewModel 格式化,同理也处理时间变量。 + * + * @param vm 包含格式化所需的内容模版及相关配置 + * @param counterValues 所有计数器的当前值,counterValues[0] 为计数器1的当前值,counterValues[1]为计数器2的当前值...... + * @param time 要用于格式化的时间,通常是当前时间 + * @return QString 格式化后的字符串 + * + */ +QString generateTxtFromBarcodeViewModel(const BarcodeViewModel& vm, const std::array counterValues, const QDateTime& time); + +#endif // _ITEM_COMMON_H_ \ No newline at end of file diff --git a/scene/PicDateItem.cpp b/scene/PicDateItem.cpp index cba65a9..d82b642 100644 --- a/scene/PicDateItem.cpp +++ b/scene/PicDateItem.cpp @@ -2,6 +2,7 @@ #include #include #include "LogInfo.h" +#include "ItemCommon.h" PicDateItem::PicDateItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type) :PicTextItem(parent, scene, type) @@ -25,7 +26,7 @@ void PicDateItem::setSource(QVariant var) if(m_model.datetimePattern.isEmpty()) return; - m_currDateTimeStr = generateDatetimeStr(QDateTime::currentDateTime()); + m_currDateTimeStr = generateTxtFromDateItemModel(m_model, QDateTime::currentDateTime()); applyModify(); } @@ -46,13 +47,13 @@ bool PicDateItem::updateDatetimeStr() return false; if(m_currDateTimeStr.isEmpty()) { - m_currDateTimeStr = generateDatetimeStr(QDateTime::currentDateTime()); + m_currDateTimeStr = generateTxtFromDateItemModel(m_model, QDateTime::currentDateTime()); applyModify(); return true; } auto now = QDateTime::currentDateTime(); - auto str = generateDatetimeStr(now); + auto str = generateTxtFromDateItemModel(m_model, now); if(str == m_currDateTimeStr) { return false; } @@ -120,81 +121,4 @@ QImage PicDateItem::itemImage() auto ret = strToImage(m_currDateTimeStr); return ret; -} - -QString PicDateItem::generateDatetimeStr(const QDateTime &datetime) -{ - QString result = m_model.datetimePattern; - - // 应用偏移量 - QDateTime applyDateTime = datetime; - if(m_model.monthsOffset != 0) { - applyDateTime = datetime.addMonths(m_model.monthsOffset); - } - else if(m_model.daysOffset != 0) { - applyDateTime = datetime.addDays(m_model.daysOffset); - } - - // 使用正则表达式匹配并替换各种格式化模式 - - // 匹配四位数年份 yyyy - int i = result.indexOf("yyyy"); - if(i != -1) { - int year = applyDateTime.date().year(); - QString yearStr = m_model.yearsMap.contains(year) ? m_model.yearsMap[year] : QString::number(year); - result.replace(i, 4, yearStr); - } - - // 匹配两位数年份 yy - i = result.indexOf("YY"); - if(i != -1) { - QString yearStr = QString::number(applyDateTime.date().year()).right(2); - result.replace(i, 2, yearStr); - } - - // 匹配两位数月份 MM - i = result.indexOf("MM"); - if(i != -1) { - result.replace(i, 2, m_model.monthsMap[applyDateTime.date().month() - 1]); - } - - // 匹配两位数日期 dd - i = result.indexOf("dd"); - if(i != -1) { - result.replace(i, 2, m_model.daysMap[applyDateTime.date().day() - 1]); - } - - // 匹配两位数小时 HH - i = result.indexOf("HH"); - if(i != -1) { - result.replace(i, 2, m_model.hoursMap[applyDateTime.time().hour()]); - } - - // 匹配两位数分钟 mm - QRegExp minutePattern("mm"); - if (result.contains(minutePattern)) { - int minute = applyDateTime.time().minute(); - result.replace(minutePattern, QString::number(minute).rightJustified(2, '0')); - } - - // 匹配两位数秒钟 ss - QRegExp secondPattern("ss"); - if (result.contains(secondPattern)) { - int second = applyDateTime.time().second(); - result.replace(secondPattern, QString::number(second).rightJustified(2, '0')); - } - - // 格式化周几 w - i = result.indexOf("w"); - if (i != -1) { - result.replace(i, 1, m_model.weeksMap[applyDateTime.date().dayOfWeek() - 1]); - } - - // 格式化年中周数 c - QRegExp weekNumberPattern("c"); - if (result.contains(weekNumberPattern)) { - result.replace(weekNumberPattern, QString::number(applyDateTime.date().weekNumber())); - } - - return result; -} +} \ No newline at end of file diff --git a/scene/PicDateItem.h b/scene/PicDateItem.h index 2e4b864..86f6e2d 100644 --- a/scene/PicDateItem.h +++ b/scene/PicDateItem.h @@ -31,8 +31,6 @@ protected: private: - QString generateDatetimeStr(const QDateTime& datetime); - QTimer m_timer; DateItemModel m_model; diff --git a/scene/ViewModels.cpp b/scene/ViewModels.cpp index 1e410fa..d62b2a5 100644 --- a/scene/ViewModels.cpp +++ b/scene/ViewModels.cpp @@ -1,31 +1,5 @@ #include "ViewModels.h" -BarcodeViewModel::BarcodeViewModel(QObject *parent) - : QObject(parent) -{ -} - -void BarcodeViewModel::setContentPattern(const QString &contentPattern) -{ - if (m_contentPattern == contentPattern) - return; - - m_contentPattern = contentPattern; - emit contentPatternChanged(); -} - -void BarcodeViewModel::setCounterViewModel(CounterViewModel counterViewModel) -{ - m_counterViewModel = std::move(counterViewModel); - emit counterViewModelChanged(); -} - -void BarcodeViewModel::setDateViewModel(DateItemModel dateViewModel) -{ - m_dateViewModel = std::move(dateViewModel); - emit dateViewModelChanged(); -} - DateItemModel DateItemModel::createDefaultReplaceModel() { DateItemModel model; diff --git a/scene/ViewModels.h b/scene/ViewModels.h index 4b74105..3ea132c 100644 --- a/scene/ViewModels.h +++ b/scene/ViewModels.h @@ -8,6 +8,11 @@ #include "SysPara.h" #include +enum InkType { + INK_TYPE_BLACK, + INK_TYPE_WHITE, +}; + /** * @brief 计数器类型 * @@ -22,13 +27,11 @@ enum COUNTER_TYPE { * */ struct CounterViewModel { - int counterType = 0; // 实际类型为 COUNTER_TYPE - int digitalNum = 0; - int letterSpace = 0; + int counterType = COUNTER_TYPE_1; // 实际类型为 COUNTER_TYPE + int digitalNum = 2; + int letterSpace = 2; int charWidth = 0; // 字符宽度,仅在 enbCustomCharWidth == true 时有意义 bool enbCustomCharWidth = false; - - SysPara* m_sysPara = nullptr; // 计数器设置界面中还依赖此对象,所以先给它 }; Q_DECLARE_METATYPE(CounterViewModel); @@ -53,91 +56,4 @@ struct DateItemModel { Q_DECLARE_METATYPE(DateItemModel); -/** - * @brief 条码设置界面所用的视图模型 - * - */ -class BarcodeViewModel : public QObject -{ - Q_OBJECT - - /** - * @brief 条形码内容模版 ,用于生成条形码 - * - * @example "1234567890{t}{c}" - * @remark 条形码内容模版中可以包含计数器变量,例如 {t} 表示当前时间,{c} 表示当前计数器值 - * @note 仅当条形码内容模版中包含日期变量或计数器变量时,属性 counterViewModel、dateViewModel 才会有意义 - */ - Q_PROPERTY(QString contentPattern READ contentPattern WRITE setContentPattern NOTIFY contentPatternChanged) - - /** - * @brief 计数器视图模型,用于填充条形码内容模版中的计数器变量 - * - */ - Q_PROPERTY(CounterViewModel counterViewModel READ counterViewModel WRITE setCounterViewModel NOTIFY counterViewModelChanged) - - /** - * @brief 日期视图模型,用于填充条形码内容模版中的日期变量 - * - */ - Q_PROPERTY(DateItemModel dateViewModel READ dateViewModel WRITE setDateViewModel NOTIFY dateViewModelChanged) - -public: - explicit BarcodeViewModel(QObject *parent = nullptr); - - /** - * @brief 获取条形码内容模版 - * - * @return QString - */ - QString contentPattern() const { return m_contentPattern; } - - /** - * @brief 设置条形码内容模版 - * - * @param contentPattern - */ - void setContentPattern(const QString& contentPattern); - - /** - * @brief 获取用于合成条形码内容的所需的计数器视图模型 - * - * @return CounterViewModel - */ - const CounterViewModel& counterViewModel() const { return m_counterViewModel; } - - /** - * @brief 设置计数器视图模型 - * @note 设置计数器视图模型后,总会触发 counterViewModelChanged 信号,因为该函数不负责检查计数器视图模型是否有更改 - * - * @param counterViewModel - */ - void setCounterViewModel(CounterViewModel counterViewModel); - - /** - * @brief 获取用于合成条形码内容的所需的日期视图模型 - * - * @return DateItemModel - */ - const DateItemModel& dateViewModel() const { return m_dateViewModel; } - - /** - * @brief 设置日期视图模型 - * @note 设置日期视图模型后,总会触发 dateViewModelChanged 信号,因为该函数不负责检查日期视图模型是否有更改 - * - * @param dateViewModel - */ - void setDateViewModel(DateItemModel dateViewModel); - -signals: - void contentPatternChanged(); - void counterViewModelChanged(); - void dateViewModelChanged(); - -private: - QString m_contentPattern; // 条形码内容模版 - CounterViewModel m_counterViewModel; // 计数器视图模型 - DateItemModel m_dateViewModel; // 日期视图模型 -}; - -#endif // VIEWMODELS_H \ No newline at end of file +#endif // VIEWMODELS_H diff --git a/testprintwidget.cpp b/testprintwidget.cpp index 0995678..d789e88 100644 --- a/testprintwidget.cpp +++ b/testprintwidget.cpp @@ -234,8 +234,12 @@ TestPrintWidget::~TestPrintWidget() } -void TestPrintWidget::bindSysPara(SysPara *sysPara){ +void TestPrintWidget::bindSysPara(SysPara *sysPara) +{ this->sysPara = sysPara; + + // 它需要这个 + m_barcodeEditor.bindSysPara(sysPara); } QPixmap TestPrintWidget::loadIcon(const QString& iconName, const QSize& size)