0504合并前提交

This commit is contained in:
2026-05-04 08:29:44 +08:00
parent cf53cbae35
commit a06c926162
22 changed files with 2007 additions and 390 deletions
Binary file not shown.
+11
View File
@@ -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 \
+2 -32
View File
@@ -132,7 +132,7 @@ QSpinBox::down-arrow {
<enum>Qt::StrongFocus</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@@ -970,37 +970,7 @@ height: 25px;
</widget>
<widget class="QWidget" name="tab_3">
<property name="styleSheet">
<string notr="true">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;
}</string>
<string notr="true"/>
</property>
<attribute name="title">
<string>计数器2</string>
+208 -59
View File
@@ -2,7 +2,41 @@
#include "ui_BarcodeEditor.h"
#include "DateFormatEditor.h"
#include "DateReplaceEditor.h"
#include "CounterEditor.h"
#include <QDebug>
#include <QKeyEvent>
// 使用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<BarcodeViewModel>::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<BarcodeViewModel> 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<BarcodeViewModel> 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<COUNTER_TYPE>(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<BarcodeViewModel> 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<DlgBarcodeFormatVM>());
m_barcodeFormatEditor.show();
}
else {
m_qrcodeFormatEditor.setViewModel(m_vm.format.value<DlgQrcodeFormatVM>());
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::onCheckBtnClicked()
{
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<QKeyEvent*>(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)
{
if(!m_vm)
return;
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<COUNTER_TYPE>(m_vm.counterViewModel.counterType),
m_vm.counterViewModel.digitalNum));
}
m_counterEditor->setFixedSize(ui->tabBarcode->size());
}
m_vm.contentPattern = content;
}
+87 -3
View File
@@ -4,9 +4,35 @@
#include <QDialog>
#include "ViewModels.h"
#include "SysPara.h"
#include "dlgQrcodeFormat.h"
#include "DlgBarcodeFormat.h"
#include <QVariant>
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<BarcodeViewModel> vm);
/**
* @brief 绑定系统参数
*
* 计数器配置选项卡所需的各个计数器的配置通过此方式提供;
* @note
* BarcodeEditor 将在 @see bindViewModel 中读取 sysPara->para.cnt1*** 或 sysPara->para.cnt2*** 相关参数,并在用户点击确认按钮时修改它们。
*
* @remark 沿用的是旧逻辑
*
* @param sysPara
*/
void bindSysPara(SysPara* sysPara) { m_sysPara = sysPara; }
QSharedPointer<BarcodeViewModel> 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<BarcodeViewModel> 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
+39 -37
View File
@@ -271,7 +271,7 @@ QSpinBox::down-arrow {
<string>日期</string>
</property>
</widget>
<widget class="QPushButton" name="btnCounter">
<widget class="QPushButton" name="btnCounter1">
<property name="geometry">
<rect>
<x>60</x>
@@ -323,38 +323,6 @@ QSpinBox::down-arrow {
</customwidgets>
<resources/>
<connections>
<connection>
<sender>closeBtn</sender>
<signal>clicked()</signal>
<receiver>BarcodeEditor</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>691</x>
<y>562</y>
</hint>
<hint type="destinationlabel">
<x>718</x>
<y>684</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBtn</sender>
<signal>clicked()</signal>
<receiver>BarcodeEditor</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>573</x>
<y>563</y>
</hint>
<hint type="destinationlabel">
<x>541</x>
<y>671</y>
</hint>
</hints>
</connection>
<connection>
<sender>lineEditContent</sender>
<signal>textChanged(QString)</signal>
@@ -378,7 +346,7 @@ QSpinBox::down-arrow {
<slot>onBtnFormatClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>518</x>
<x>412</x>
<y>231</y>
</hint>
<hint type="destinationlabel">
@@ -395,7 +363,7 @@ QSpinBox::down-arrow {
<hints>
<hint type="sourcelabel">
<x>562</x>
<y>325</y>
<y>255</y>
</hint>
<hint type="destinationlabel">
<x>915</x>
@@ -404,14 +372,14 @@ QSpinBox::down-arrow {
</hints>
</connection>
<connection>
<sender>btnCounter</sender>
<sender>btnCounter1</sender>
<signal>clicked()</signal>
<receiver>BarcodeEditor</receiver>
<slot>onBtnCounterClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>553</x>
<y>370</y>
<y>300</y>
</hint>
<hint type="destinationlabel">
<x>819</x>
@@ -419,11 +387,45 @@ QSpinBox::down-arrow {
</hint>
</hints>
</connection>
<connection>
<sender>checkBtn</sender>
<signal>clicked()</signal>
<receiver>BarcodeEditor</receiver>
<slot>onCheckBtnClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>543</x>
<y>558</y>
</hint>
<hint type="destinationlabel">
<x>581</x>
<y>705</y>
</hint>
</hints>
</connection>
<connection>
<sender>closeBtn</sender>
<signal>clicked()</signal>
<receiver>BarcodeEditor</receiver>
<slot>onCloseBtnClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>689</x>
<y>561</y>
</hint>
<hint type="destinationlabel">
<x>708</x>
<y>734</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>onContentChanged(QString)</slot>
<slot>onBtnFormatClicked()</slot>
<slot>onBtnDatetimeClicked()</slot>
<slot>onBtnCounterClicked()</slot>
<slot>onCheckBtnClicked()</slot>
<slot>onCloseBtnClicked()</slot>
</slots>
</ui>
+138
View File
@@ -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<int>::of(&QComboBox::currentIndexChanged), this, &CounterEditor::onCounterTypeChanged);
connect(ui->cbBoxDigitalNum, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CounterEditor::onDigitalNumChanged);
connect(ui->spinBoxCnt2StartValue, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int) {fetchCounterConfigFromView();} );
connect(ui->spinBoxCnt2EndValue, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int) {fetchCounterConfigFromView();} );
connect(ui->spinBoxCnt2RepeateCnt, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int) {fetchCounterConfigFromView();} );
connect(ui->spinBoxCnt2StepValue, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int) {fetchCounterConfigFromView();} );
connect(ui->spinBoxCnt2CurrValue, QOverload<int>::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());
}
+69
View File
@@ -0,0 +1,69 @@
#ifndef COUNTEREDITOR_H
#define COUNTEREDITOR_H
#include <QWidget>
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
+603
View File
@@ -0,0 +1,603 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CounterEditor</class>
<widget class="QWidget" name="CounterEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>732</width>
<height>522</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QWidget {
font-size: 16px;
}</string>
</property>
<widget class="QSpinBox" name="spinBoxCnt2EndValue">
<property name="geometry">
<rect>
<x>369</x>
<y>122</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="maximum">
<number>9999999</number>
</property>
<property name="value">
<number>9999</number>
</property>
</widget>
<widget class="QLabel" name="label_27">
<property name="geometry">
<rect>
<x>475</x>
<y>122</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>重复数: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QSpinBox" name="spinBoxCnt2RepeateCnt">
<property name="geometry">
<rect>
<x>581</x>
<y>122</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
</widget>
<widget class="QSpinBox" name="spinBoxCnt2StepValue">
<property name="geometry">
<rect>
<x>157</x>
<y>179</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="minimum">
<number>-49999999</number>
</property>
<property name="maximum">
<number>49999999</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
<widget class="QLabel" name="labelCnt2CurrValue">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>475</x>
<y>179</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="font">
<font>
<pointsize>-1</pointsize>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLabel" name="label_25">
<property name="geometry">
<rect>
<x>51</x>
<y>122</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>起始值: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QSpinBox" name="spinBoxCnt2StartValue">
<property name="geometry">
<rect>
<x>157</x>
<y>122</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximum">
<number>999999</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
<widget class="QLabel" name="label_11">
<property name="geometry">
<rect>
<x>263</x>
<y>122</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>结束值: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QSpinBox" name="spinBoxCnt2CurrValue">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>369</x>
<y>179</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>999999999</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
<widget class="QWidget" name="widget_2" native="true">
<property name="geometry">
<rect>
<x>270</x>
<y>179</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBoxResetCnt2CurrValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QRadioButton::indicator {
width: 25px;
height: 25px;
}</string>
</property>
<property name="text">
<string>当前值: </string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="widget_3" native="true">
<property name="geometry">
<rect>
<x>56</x>
<y>179</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="eleCNT2IncEn">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QRadioButton::indicator {
width: 25px;
height: 25px;
}</string>
</property>
<property name="text">
<string>增量值: </string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>70</x>
<y>60</y>
<width>81</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>计数器ID:</string>
</property>
</widget>
<widget class="QComboBox" name="cbBoxCounterType">
<property name="geometry">
<rect>
<x>160</x>
<y>60</y>
<width>121</width>
<height>31</height>
</rect>
</property>
<item>
<property name="text">
<string>计数器1</string>
</property>
</item>
<item>
<property name="text">
<string>计数器2</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>370</x>
<y>60</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>计数器位数:</string>
</property>
</widget>
<widget class="QComboBox" name="cbBoxDigitalNum">
<property name="geometry">
<rect>
<x>470</x>
<y>60</y>
<width>101</width>
<height>31</height>
</rect>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>3</string>
</property>
</item>
<item>
<property name="text">
<string>4</string>
</property>
</item>
<item>
<property name="text">
<string>5</string>
</property>
</item>
<item>
<property name="text">
<string>6</string>
</property>
</item>
<item>
<property name="text">
<string>7</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
</widget>
</widget>
<resources/>
<connections/>
</ui>
+51
View File
@@ -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;
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef DLGBARCODEFORMAT_H
#define DLGBARCODEFORMAT_H
#include <QDialog>
#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
+288
View File
@@ -0,0 +1,288 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgBarcodeFormat</class>
<widget class="QDialog" name="DlgBarcodeFormat">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>510</width>
<height>380</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="styleSheet">
<string notr="true">QWidget{
font-size: 16px;
}</string>
</property>
<widget class="QSpinBox" name="BarCodeScale">
<property name="geometry">
<rect>
<x>300</x>
<y>150</y>
<width>60</width>
<height>31</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>70</x>
<y>120</y>
<width>91</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>条形码高度</string>
</property>
</widget>
<widget class="QComboBox" name="BarCodeDot">
<property name="geometry">
<rect>
<x>190</x>
<y>150</y>
<width>71</width>
<height>31</height>
</rect>
</property>
<item>
<property name="text">
<string>1点</string>
</property>
</item>
<item>
<property name="text">
<string>2点</string>
</property>
</item>
<item>
<property name="text">
<string>3点</string>
</property>
</item>
<item>
<property name="text">
<string>4点</string>
</property>
</item>
<item>
<property name="text">
<string>5点</string>
</property>
</item>
<item>
<property name="text">
<string>6点</string>
</property>
</item>
</widget>
<widget class="QCheckBox" name="checkBoxAddText">
<property name="geometry">
<rect>
<x>330</x>
<y>240</y>
<width>83</width>
<height>16</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>增加数字行</string>
</property>
</widget>
<widget class="QComboBox" name="BarCodeHeigh">
<property name="geometry">
<rect>
<x>70</x>
<y>150</y>
<width>71</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="comboBoxInkColor">
<property name="geometry">
<rect>
<x>300</x>
<y>70</y>
<width>81</width>
<height>31</height>
</rect>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>黑墨</string>
</property>
</item>
<item>
<property name="text">
<string>白墨</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label_7">
<property name="geometry">
<rect>
<x>190</x>
<y>120</y>
<width>76</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>条码宽度</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>70</x>
<y>40</y>
<width>140</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>条形码类型</string>
</property>
</widget>
<widget class="QComboBox" name="BarCodeType">
<property name="geometry">
<rect>
<x>70</x>
<y>70</y>
<width>140</width>
<height>31</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>140</width>
<height>0</height>
</size>
</property>
</widget>
<widget class="QLabel" name="lab123">
<property name="geometry">
<rect>
<x>300</x>
<y>40</y>
<width>76</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>墨水类型</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>300</x>
<y>120</y>
<width>129</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>显示缩放</string>
</property>
</widget>
<widget class="QPushButton" name="checkBtn">
<property name="geometry">
<rect>
<x>370</x>
<y>300</y>
<width>101</width>
<height>50</height>
</rect>
</property>
<property name="text">
<string>✓</string>
</property>
</widget>
</widget>
<tabstops>
<tabstop>BarCodeType</tabstop>
<tabstop>comboBoxInkColor</tabstop>
<tabstop>BarCodeHeigh</tabstop>
<tabstop>BarCodeDot</tabstop>
<tabstop>BarCodeScale</tabstop>
<tabstop>checkBoxAddText</tabstop>
<tabstop>checkBtn</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>checkBtn</sender>
<signal>clicked()</signal>
<receiver>DlgBarcodeFormat</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>412</x>
<y>323</y>
</hint>
<hint type="destinationlabel">
<x>417</x>
<y>379</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+18
View File
@@ -12,3 +12,21 @@ 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;
}
+38
View File
@@ -2,11 +2,43 @@
#define DLGQRCODEFORMAT_H
#include <QDialog>
#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
@@ -15,8 +47,14 @@ public:
explicit DlgQrcodeFormat(QWidget *parent = nullptr);
~DlgQrcodeFormat();
void setViewModel(DlgQrcodeFormatVM vm);
DlgQrcodeFormatVM viewModel();
private:
Ui::DlgQrcodeFormat *ui;
DlgQrcodeFormatVM m_vm;
};
#endif // DLGQRCODEFORMAT_H
+215 -4
View File
@@ -1,18 +1,229 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgQrcodeFormat</class>
<widget name="DlgQrcodeFormat" class="QDialog">
<widget class="QDialog" name="DlgQrcodeFormat">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>510</width>
<height>380</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="styleSheet">
<string notr="true">QWidget{
font-size: 16px;
}</string>
</property>
<widget class="QComboBox" name="comboBoxType">
<property name="geometry">
<rect>
<x>40</x>
<y>60</y>
<width>251</width>
<height>31</height>
</rect>
</property>
<item>
<property name="text">
<string>DataMatrix</string>
</property>
</item>
<item>
<property name="text">
<string>QRCode</string>
</property>
</item>
</widget>
<widget class="QComboBox" name="comboBoxInkColor">
<property name="geometry">
<rect>
<x>40</x>
<y>130</y>
<width>251</width>
<height>31</height>
</rect>
</property>
<item>
<property name="text">
<string>正相打印</string>
</property>
</item>
<item>
<property name="text">
<string>反相打印</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>40</x>
<y>180</y>
<width>141</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>DM码尺寸:</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
<widget class="QComboBox" name="comboBox_DMType">
<property name="geometry">
<rect>
<x>40</x>
<y>210</y>
<width>157</width>
<height>31</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<item>
<property name="text">
<string>默认</string>
</property>
</item>
<item>
<property name="text">
<string>8 x 18</string>
</property>
</item>
<item>
<property name="text">
<string>8 x 32</string>
</property>
</item>
<item>
<property name="text">
<string>12 x 26</string>
</property>
</item>
<item>
<property name="text">
<string>12 x 36</string>
</property>
</item>
<item>
<property name="text">
<string>16 x 36</string>
</property>
</item>
<item>
<property name="text">
<string>16 x 48</string>
</property>
</item>
</widget>
<widget class="QComboBox" name="comboBox_QRCodeLevel">
<property name="geometry">
<rect>
<x>210</x>
<y>210</y>
<width>156</width>
<height>31</height>
</rect>
</property>
<item>
<property name="text">
<string>低级</string>
</property>
</item>
<item>
<property name="text">
<string>中级</string>
</property>
</item>
<item>
<property name="text">
<string>高级</string>
</property>
</item>
<item>
<property name="text">
<string>超高级</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>40</x>
<y>21</y>
<width>181</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>类型</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>40</x>
<y>101</y>
<width>141</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>墨水类型</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
<widget class="QPushButton" name="checkBtn">
<property name="geometry">
<rect>
<x>370</x>
<y>300</y>
<width>101</width>
<height>50</height>
</rect>
</property>
<property name="text">
<string>✓</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
<connections>
<connection>
<sender>checkBtn</sender>
<signal>clicked()</signal>
<receiver>DlgQrcodeFormat</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>423</x>
<y>327</y>
</hint>
<hint type="destinationlabel">
<x>463</x>
<y>504</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+98
View File
@@ -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<int, 2> 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;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef _ITEM_COMMON_H_
#define _ITEM_COMMON_H_
#include "ViewModels.h"
#include <QDateTime>
#include <QString>
#include <QVector>
#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<int, 2> counterValues, const QDateTime& time);
#endif // _ITEM_COMMON_H_
+4 -80
View File
@@ -2,6 +2,7 @@
#include <QDebug>
#include <QRegExp>
#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;
}
@@ -121,80 +122,3 @@ 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;
}
-2
View File
@@ -31,8 +31,6 @@ protected:
private:
QString generateDatetimeStr(const QDateTime& datetime);
QTimer m_timer;
DateItemModel m_model;
-26
View File
@@ -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;
+8 -92
View File
@@ -8,6 +8,11 @@
#include "SysPara.h"
#include <QMap>
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
+5 -1
View File
@@ -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)