first commit

This commit is contained in:
2026-04-29 14:10:10 +08:00
commit b28556d43d
1558 changed files with 241386 additions and 0 deletions
+195
View File
@@ -0,0 +1,195 @@
#include "BarcodeEditor.h"
#include "ui_BarcodeEditor.h"
#include "DateFormatEditor.h"
#include "DateReplaceEditor.h"
#include <QDebug>
BarcodeEditor::BarcodeEditor(QWidget *parent) :
QDialog(parent),
ui(new Ui::BarcodeEditor)
{
ui->setupUi(this);
setWindowModality(Qt::NonModal);
m_dateFormatEditor = new DateFormatEditor();
m_dateReplaceEditor = new DateReplaceEditor();
m_vm = QSharedPointer<BarcodeViewModel>::create();
m_vm->setDateViewModel(DateItemModel::createDefaultReplaceModel());
m_dateReplaceEditor->setDateModel(m_vm->dateViewModel());
}
BarcodeEditor::~BarcodeEditor()
{
auto index = ui->tabWidget->indexOf(m_dateFormatEditor);
if(index != -1) {
ui->tabWidget->removeTab(index);
}
index = ui->tabWidget->indexOf(m_dateReplaceEditor);
if(index != -1) {
ui->tabWidget->removeTab(index);
}
delete m_dateFormatEditor;
delete m_dateReplaceEditor;
delete ui;
}
void BarcodeEditor::bindViewModel(QSharedPointer<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();
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);
}
DateFormatEditorVM dateFormatVM;
if(m_vm->dateViewModel().daysOffset > 0) {
dateFormatVM.expirationValue = m_vm->dateViewModel().daysOffset;
dateFormatVM.expirationType = EXPIRATION_TYPE_DAY;
}
else if(m_vm->dateViewModel().monthsOffset > 0) {
dateFormatVM.expirationValue = m_vm->dateViewModel().monthsOffset;
dateFormatVM.expirationType = EXPIRATION_TYPE_MONTH;
}
dateFormatVM.pattern = m_vm->dateViewModel().datetimePattern;
m_dateFormatEditor->setViewModel(dateFormatVM);
m_dateReplaceEditor->setDateModel(m_vm->dateViewModel());
if(vm->contentPattern().contains("{t}")) {
if(ui->tabWidget->indexOf(m_dateFormatEditor) == -1) {
ui->tabWidget->addTab(m_dateFormatEditor, tr(u8"日期/时间"));
}
m_dateFormatEditor->setFixedSize(ui->tabBarcode->size());
if(ui->tabWidget->indexOf(m_dateReplaceEditor) == -1) {
ui->tabWidget->addTab(m_dateReplaceEditor, tr(u8"代替"));
}
m_dateReplaceEditor->setFixedSize(ui->tabBarcode->size());
}
else {
auto index = ui->tabWidget->indexOf(m_dateFormatEditor);
if(index != -1) {
ui->tabWidget->removeTab(index);
}
index = ui->tabWidget->indexOf(m_dateReplaceEditor);
if(index != -1) {
ui->tabWidget->removeTab(index);
}
}
if(vm->contentPattern().contains("{c}")) {
// TODO:: 添加计数器选项卡
}
}
QSharedPointer<BarcodeViewModel> BarcodeEditor::viewModel() const
{
return m_vm;
}
void BarcodeEditor::onBtnFormatClicked()
{
if(!m_vm)
return;
// 显示对话框,用于针对于条形码、二维码的格式调整,例如二维码的编码类型、大小、条形码的宽度、等等
}
void BarcodeEditor::onBtnDatetimeClicked()
{
if(ui->lineEditContent->text().contains("{t}")) {
qInfo() << "Cannot add datetime format twice";
return;
}
ui->lineEditContent->insert("{t}");
ui->tabWidget->setCurrentIndex(1);
}
void BarcodeEditor::onBtnCounterClicked()
{
if(ui->lineEditContent->text().contains("{c}")) {
qInfo() << "Cannot add counter format twice";
return;
}
ui->lineEditContent->insert("{c}");
}
void BarcodeEditor::onContentChanged(QString content)
{
if(!m_vm)
return;
if(!content.contains("{t}")) {
auto index = ui->tabWidget->indexOf(m_dateFormatEditor);
if(index != -1) {
ui->tabWidget->removeTab(index);
}
index = ui->tabWidget->indexOf(m_dateReplaceEditor);
if(index != -1) {
ui->tabWidget->removeTab(index);
}
}
else {
if(ui->tabWidget->indexOf(m_dateFormatEditor) == -1) {
ui->tabWidget->addTab(m_dateFormatEditor, tr(u8"日期/时间"));
}
m_dateFormatEditor->setFixedSize(ui->tabBarcode->size());
if(ui->tabWidget->indexOf(m_dateReplaceEditor) == -1) {
ui->tabWidget->addTab(m_dateReplaceEditor, tr(u8"代替"));
}
m_dateReplaceEditor->setFixedSize(ui->tabBarcode->size());
DateFormatEditorVM dateFormatVM;
if(m_vm->dateViewModel().daysOffset > 0) {
dateFormatVM.expirationValue = m_vm->dateViewModel().daysOffset;
dateFormatVM.expirationType = EXPIRATION_TYPE_DAY;
}
else if(m_vm->dateViewModel().monthsOffset > 0) {
dateFormatVM.expirationValue = m_vm->dateViewModel().monthsOffset;
dateFormatVM.expirationType = EXPIRATION_TYPE_MONTH;
}
dateFormatVM.pattern = m_vm->dateViewModel().datetimePattern;
m_dateFormatEditor->setViewModel(dateFormatVM);
m_dateReplaceEditor->setDateModel(m_vm->dateViewModel());
}
m_vm->setContentPattern(content);
}
+63
View File
@@ -0,0 +1,63 @@
#ifndef BARCODEEDITOR_H
#define BARCODEEDITOR_H
#include <QDialog>
#include "ViewModels.h"
class DateFormatEditor;
class DateReplaceEditor;
namespace Ui {
class BarcodeEditor;
}
class BarcodeEditor : public QDialog
{
Q_OBJECT
public:
explicit BarcodeEditor(QWidget *parent = nullptr);
~BarcodeEditor();
void bindViewModel(QSharedPointer<BarcodeViewModel> vm);
QSharedPointer<BarcodeViewModel> viewModel() const;
private slots:
/**
* @brief 条形码内容改变时触发
*
* @param content
*/
void onContentChanged(QString content);
/**
* @brief 条形码、二维码格式更改按钮点击时触发
*
*/
void onBtnFormatClicked();
/**
* @brief 日期按钮点击时触发
*
*/
void onBtnDatetimeClicked();
/**
* @brief 计数器按钮点击时触发
*
*/
void onBtnCounterClicked();
private:
Ui::BarcodeEditor *ui;
QSharedPointer<BarcodeViewModel> m_vm;
DateFormatEditor *m_dateFormatEditor = nullptr;
DateReplaceEditor *m_dateReplaceEditor = nullptr;
};
#endif // BARCODEEDITOR_H
+429
View File
@@ -0,0 +1,429 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BarcodeEditor</class>
<widget class="QDialog" name="BarcodeEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true">QWidget {
font-size: 16px;
}
QPushButton#closeBtn, QPushButton#checkBtn{
background-color: #E6F7FF;
border: 1px solid #87CEEB;
border-radius: 4px;
font-size: 24px;
color: #228B22;
}
QPushButton#closeBtn:hover,QPushButton#checkBtn:hover{
background-color: #D1E9FF;
}
QPushButton#closeBtn:pressed,QPushButton#checkBtn:pressed{
background-color: #BAE7FF;
}
QPushButton {
background-color: #5396C1;
color: #ffffff;
border: 1px solid #000000;
border-radius: 3px;
font-size: 18px;
font-weight:500;
width: 180px;
height: 90px;
}
QPushButton:hover {
background-color: #5396C1;
}
QPushButton:disabled {
background-color: #7C828E;
color: #606060;
border-color: #808080;
}
QComboBox {
border: 1px solid #000000;
border-radius: 3px;
font-size: 14px;
width: 180px;
height: 90px;
padding-left: 10px; /* 文字左边距,避免紧贴边缘 */
}
/* 下拉箭头区域 */
QComboBox::drop-down {
border: 1px solid #333333;
border-radius: 3px;
width: 30px; /* 箭头区域宽度 */
background-color: #5396C1;
}
/* 下拉箭头图标 */
QComboBox::down-arrow {
image: url(image/down_white.png);
width: 16px; /* 图标显示宽度 */
height: 16px; /* 图标显示高度 */
}
/* 悬停状态 */
QComboBox:hover {
background-color: #efefef;
}
// 下拉框
QComboBox QAbstractItemView {
border: 1px solid #000000;
border-radius: 3px;
font-size: 14px;
selection-background-color: #5396C1; /* 选中项背景色(稍深) */
selection-color: #ffffff;
}
QSpinBox::up-button {
width: 16px; /* 图标显示宽度 */
height: 16px; /* 图标显示高度 */
border: 1px solid #333333;
border-radius: 3px;
background-color: #5396C1;
}
QSpinBox::up-arrow {
image: url(image/up_white.png);
}
QSpinBox::down-button {
width: 16px; /* 图标显示宽度 */
height: 16px; /* 图标显示高度 */
border: 1px solid #333333;
border-radius: 3px;
background-color: #5396C1;
}
QSpinBox::down-arrow {
image: url(image/down_white.png);
}
</string>
</property>
<property name="modal">
<bool>false</bool>
</property>
<widget class="QPushButton" name="checkBtn">
<property name="geometry">
<rect>
<x>520</x>
<y>540</y>
<width>101</width>
<height>50</height>
</rect>
</property>
<property name="text">
<string>✓</string>
</property>
</widget>
<widget class="QPushButton" name="closeBtn">
<property name="geometry">
<rect>
<x>640</x>
<y>540</y>
<width>101</width>
<height>50</height>
</rect>
</property>
<property name="text">
<string>✕</string>
</property>
</widget>
<widget class="QTabWidget" name="tabWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>771</width>
<height>471</height>
</rect>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="tabGeneralSettings">
<attribute name="title">
<string>整体设置</string>
</attribute>
<widget class="ItemGeneralSettings" name="widGeneralSettings" native="true">
<property name="geometry">
<rect>
<x>-1</x>
<y>-1</y>
<width>771</width>
<height>441</height>
</rect>
</property>
</widget>
</widget>
<widget class="QWidget" name="tabBarcode">
<attribute name="title">
<string>条形码</string>
</attribute>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>40</x>
<y>20</y>
<width>81</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>内容</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEditContent">
<property name="geometry">
<rect>
<x>40</x>
<y>50</y>
<width>481</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>40</x>
<y>110</y>
<width>81</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>类型</string>
</property>
</widget>
<widget class="QComboBox" name="cbBoxType">
<property name="geometry">
<rect>
<x>40</x>
<y>140</y>
<width>191</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="QPushButton" name="btnFormat">
<property name="geometry">
<rect>
<x>260</x>
<y>140</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>条形码格式</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>420</x>
<y>120</y>
<width>261</width>
<height>291</height>
</rect>
</property>
<property name="title">
<string>嵌入</string>
</property>
<widget class="QPushButton" name="btnDatetime">
<property name="geometry">
<rect>
<x>60</x>
<y>40</y>
<width>131</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>日期</string>
</property>
</widget>
<widget class="QPushButton" name="btnCounter">
<property name="geometry">
<rect>
<x>60</x>
<y>90</y>
<width>131</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>计数器</string>
</property>
</widget>
</widget>
</widget>
</widget>
<widget class="QWidget" name="widget" native="true">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>38</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:#4E679F;</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="styleSheet">
<string notr="true">color:#ffffff;</string>
</property>
<property name="text">
<string>条形码编辑</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>ItemGeneralSettings</class>
<extends>QWidget</extends>
<header>scene/ItemGeneralSettings.h</header>
<container>1</container>
</customwidget>
</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>
<receiver>BarcodeEditor</receiver>
<slot>onContentChanged(QString)</slot>
<hints>
<hint type="sourcelabel">
<x>199</x>
<y>144</y>
</hint>
<hint type="destinationlabel">
<x>-130</x>
<y>136</y>
</hint>
</hints>
</connection>
<connection>
<sender>btnFormat</sender>
<signal>clicked()</signal>
<receiver>BarcodeEditor</receiver>
<slot>onBtnFormatClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>518</x>
<y>231</y>
</hint>
<hint type="destinationlabel">
<x>895</x>
<y>230</y>
</hint>
</hints>
</connection>
<connection>
<sender>btnDatetime</sender>
<signal>clicked()</signal>
<receiver>BarcodeEditor</receiver>
<slot>onBtnDatetimeClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>562</x>
<y>325</y>
</hint>
<hint type="destinationlabel">
<x>915</x>
<y>326</y>
</hint>
</hints>
</connection>
<connection>
<sender>btnCounter</sender>
<signal>clicked()</signal>
<receiver>BarcodeEditor</receiver>
<slot>onBtnCounterClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>553</x>
<y>370</y>
</hint>
<hint type="destinationlabel">
<x>819</x>
<y>382</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>onContentChanged(QString)</slot>
<slot>onBtnFormatClicked()</slot>
<slot>onBtnDatetimeClicked()</slot>
<slot>onBtnCounterClicked()</slot>
</slots>
</ui>
+105
View File
@@ -0,0 +1,105 @@
#include "DateFormatEditor.h"
#include "ui_DateFormatEditor.h"
DateFormatEditor::DateFormatEditor(QWidget *parent) :
QWidget(parent),
ui(new Ui::DateFormatEditor)
{
ui->setupUi(this);
connect(ui->btnPoint,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnColon,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnComma,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnSlash,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnSemicolon,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnUnderline,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnDash,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnBackSpace,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnHour,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnMinute,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnSecond,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnDay,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnMonth,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnYear4,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnYear2,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnWeekOfYear,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnWeek,&QPushButton::clicked,this,&DateFormatEditor::buttonClickedSlot);
connect(ui->btnSpace, &QPushButton::clicked, this, &DateFormatEditor::buttonClickedSlot);
setViewModel(m_vm);
}
DateFormatEditor::~DateFormatEditor()
{
delete ui;
}
void DateFormatEditor::setViewModel(DateFormatEditorVM vm)
{
m_vm = std::move(vm);
auto b = ui->lineEdit_DateFormat->blockSignals(true);
ui->lineEdit_DateFormat->setText(m_vm.pattern);
ui->lineEdit_DateFormat->blockSignals(b);
b = ui->expirationNumCBox->blockSignals(true);
ui->expirationNumCBox->setValue(m_vm.expirationValue);
ui->expirationNumCBox->blockSignals(b);
b = ui->expirationCBox->blockSignals(true);
ui->expirationCBox->setCurrentIndex(m_vm.expirationType);
ui->expirationCBox->blockSignals(b);
}
DateFormatEditorVM DateFormatEditor::viewModel()
{
m_vm.pattern = ui->lineEdit_DateFormat->text();
m_vm.expirationValue = ui->expirationNumCBox->value();
m_vm.expirationType = (EXPIRATION_TYPE)(ui->expirationCBox->currentIndex());
return m_vm;
}
void DateFormatEditor::buttonClickedSlot()
{
QPushButton* btn = qobject_cast<QPushButton*>(sender());
if(btn == ui->btnPoint){
ui->lineEdit_DateFormat->insert(".");
}else if(btn == ui->btnColon){
ui->lineEdit_DateFormat->insert(":");
}else if(btn == ui->btnComma){
ui->lineEdit_DateFormat->insert(",");
}else if(btn == ui->btnSlash){
ui->lineEdit_DateFormat->insert("/");
}else if(btn == ui->btnSemicolon){
ui->lineEdit_DateFormat->insert(";");
}else if(btn == ui->btnUnderline){
ui->lineEdit_DateFormat->insert("_");
}else if(btn == ui->btnDash){
ui->lineEdit_DateFormat->insert("-");
}else if(btn == ui->btnBackSpace){
ui->lineEdit_DateFormat->backspace();
}else if(btn == ui->btnHour){
ui->lineEdit_DateFormat->insert("HH");
}else if(btn == ui->btnMinute){
ui->lineEdit_DateFormat->insert("mm");
}else if(btn == ui->btnSecond){
ui->lineEdit_DateFormat->insert("ss");
}else if(btn == ui->btnDay){
ui->lineEdit_DateFormat->insert("dd");
}else if(btn == ui->btnMonth){
ui->lineEdit_DateFormat->insert("MM");
}else if(btn == ui->btnYear4){
ui->lineEdit_DateFormat->insert("yyyy");
}else if(btn == ui->btnYear2){
ui->lineEdit_DateFormat->insert("YY");
}
else if(btn == ui->btnWeekOfYear){
ui->lineEdit_DateFormat->insert("c");
}
else if(btn == ui->btnWeek){
ui->lineEdit_DateFormat->insert("w");
}
else if(btn == ui->btnSpace)
ui->lineEdit_DateFormat->insert(" ");
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef DATEFORMATEDITOR_H
#define DATEFORMATEDITOR_H
#include <QWidget>
#include "ViewModels.h"
namespace Ui {
class DateFormatEditor;
}
enum EXPIRATION_TYPE {
EXPIRATION_TYPE_NONE = -1,
EXPIRATION_TYPE_DAY,
EXPIRATION_TYPE_MONTH,
EXPIRATION_TYPE_RESERVED,
};
struct DateFormatEditorVM {
QString pattern;
int expirationValue = 0;
EXPIRATION_TYPE expirationType = EXPIRATION_TYPE_NONE;
};
class DateFormatEditor : public QWidget
{
Q_OBJECT
public:
explicit DateFormatEditor(QWidget *parent = nullptr);
~DateFormatEditor();
void setViewModel(DateFormatEditorVM vm);
DateFormatEditorVM viewModel();
private slots:
void buttonClickedSlot();
private:
Ui::DateFormatEditor *ui;
DateFormatEditorVM m_vm;
};
#endif // DATEFORMATEDITOR_H
+443
View File
@@ -0,0 +1,443 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DateFormatEditor</class>
<widget class="QWidget" name="DateFormatEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>764</width>
<height>361</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true">QWidget{
font-size: 16px;
}
QPushButton {
background-color: #5396C1;
color: #ffffff;
border: 1px solid #000000;
border-radius: 3px;
font-size: 18px;
font-weight:500;
width: 180px;
height: 90px;
}
QPushButton:hover {
background-color: #5396C1;
}
QPushButton:disabled {
background-color: #7C828E;
color: #606060;
border-color: #808080;
}
QComboBox {
border: 1px solid #000000;
border-radius: 3px;
font-size: 14px;
width: 180px;
height: 90px;
padding-left: 10px; /* 文字左边距,避免紧贴边缘 */
}
/* 下拉箭头区域 */
QComboBox::drop-down {
border: 1px solid #333333;
border-radius: 3px;
width: 30px; /* 箭头区域宽度 */
background-color: #5396C1;
}
/* 下拉箭头图标 */
QComboBox::down-arrow {
image: url(image/down_white.png);
width: 16px; /* 图标显示宽度 */
height: 16px; /* 图标显示高度 */
}
/* 悬停状态 */
QComboBox:hover {
background-color: #efefef;
}
// 下拉框
QComboBox QAbstractItemView {
border: 1px solid #000000;
border-radius: 3px;
font-size: 14px;
selection-background-color: #5396C1; /* 选中项背景色(稍深) */
selection-color: #ffffff;
}</string>
</property>
<widget class="QWidget" name="panel" native="true">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>761</width>
<height>361</height>
</rect>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>内容</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_DateFormat">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>60</x>
<y>50</y>
<width>371</width>
<height>30</height>
</rect>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>470</x>
<y>26</y>
<width>111</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>有效期限</string>
</property>
</widget>
<widget class="QComboBox" name="expirationCBox">
<property name="geometry">
<rect>
<x>510</x>
<y>50</y>
<width>231</width>
<height>30</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true"/>
</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>
</widget>
<widget class="QPushButton" name="btnPoint">
<property name="geometry">
<rect>
<x>20</x>
<y>100</y>
<width>45</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>.</string>
</property>
</widget>
<widget class="QPushButton" name="btnColon">
<property name="geometry">
<rect>
<x>70</x>
<y>100</y>
<width>45</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>:</string>
</property>
</widget>
<widget class="QPushButton" name="btnComma">
<property name="geometry">
<rect>
<x>120</x>
<y>100</y>
<width>45</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>,</string>
</property>
</widget>
<widget class="QPushButton" name="btnSlash">
<property name="geometry">
<rect>
<x>170</x>
<y>100</y>
<width>45</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>/</string>
</property>
</widget>
<widget class="QPushButton" name="btnSemicolon">
<property name="geometry">
<rect>
<x>220</x>
<y>100</y>
<width>45</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>;</string>
</property>
</widget>
<widget class="QPushButton" name="btnUnderline">
<property name="geometry">
<rect>
<x>270</x>
<y>100</y>
<width>45</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>_</string>
</property>
</widget>
<widget class="QPushButton" name="btnDash">
<property name="geometry">
<rect>
<x>320</x>
<y>100</y>
<width>45</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
<widget class="QPushButton" name="btnHour">
<property name="geometry">
<rect>
<x>20</x>
<y>150</y>
<width>95</width>
<height>35</height>
</rect>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>小时</string>
</property>
</widget>
<widget class="QPushButton" name="btnMinute">
<property name="geometry">
<rect>
<x>150</x>
<y>150</y>
<width>95</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>分钟</string>
</property>
</widget>
<widget class="QPushButton" name="btnSecond">
<property name="geometry">
<rect>
<x>270</x>
<y>150</y>
<width>95</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>秒钟</string>
</property>
</widget>
<widget class="QPushButton" name="btnMonth">
<property name="geometry">
<rect>
<x>150</x>
<y>200</y>
<width>95</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>月</string>
</property>
</widget>
<widget class="QPushButton" name="btnYear4">
<property name="geometry">
<rect>
<x>270</x>
<y>200</y>
<width>95</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>年2026</string>
</property>
</widget>
<widget class="QPushButton" name="btnDay">
<property name="geometry">
<rect>
<x>20</x>
<y>200</y>
<width>95</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>日</string>
</property>
</widget>
<widget class="QPushButton" name="btnWeekOfYear">
<property name="geometry">
<rect>
<x>20</x>
<y>250</y>
<width>221</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>年中第几周</string>
</property>
</widget>
<widget class="QPushButton" name="btnYear2">
<property name="geometry">
<rect>
<x>270</x>
<y>250</y>
<width>95</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>年26</string>
</property>
</widget>
<widget class="QPushButton" name="btnWeek">
<property name="geometry">
<rect>
<x>20</x>
<y>300</y>
<width>141</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>周几</string>
</property>
</widget>
<widget class="QPushButton" name="btnSpace">
<property name="geometry">
<rect>
<x>210</x>
<y>300</y>
<width>155</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>空格</string>
</property>
</widget>
<widget class="QPushButton" name="btnBackSpace">
<property name="geometry">
<rect>
<x>370</x>
<y>100</y>
<width>81</width>
<height>35</height>
</rect>
</property>
<property name="text">
<string>&lt;------</string>
</property>
</widget>
<widget class="QSpinBox" name="expirationNumCBox">
<property name="geometry">
<rect>
<x>540</x>
<y>100</y>
<width>111</width>
<height>31</height>
</rect>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>660</x>
<y>100</y>
<width>31</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>700</x>
<y>100</y>
<width>31</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>+</string>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
+603
View File
@@ -0,0 +1,603 @@
#include "DateReplaceEditor.h"
#include "ui_DateReplaceEditor.h"
#include <QDate>
#include <QLineEdit>
#include <functional>
#include <QMap>
extern unsigned char vartypeR;
extern QMap<int,QMap<int,QString>> replaceValueMap;
DateReplaceEditor::DateReplaceEditor(QWidget *parent) :
QWidget(parent),
ui(new Ui::DateReplaceEditor)
{
ui->setupUi(this);
init();
initReplaceValue();
applyStyleSheet();
}
DateReplaceEditor::~DateReplaceEditor()
{
delete ui;
}
DateItemModel DateReplaceEditor::dateModel()
{
DateItemModel model;
model.dataMap = dataList;
model.weeksMap = weekList;
model.hoursMap = hourList;
model.monthsMap = monthList;
model.daysMap = dayList;
for (int i = 0; i < yearInitList.size() && i < yearList.size(); ++i) {
model.yearsMap[yearInitList[i]] = yearList[i];
}
return model;
}
void DateReplaceEditor::setDateModel(const DateItemModel &model)
{
dataList = model.dataMap;
weekList = model.weeksMap;
hourList = model.hoursMap;
monthList = model.monthsMap;
dayList = model.daysMap;
yearInitList = model.yearsMap.keys();
yearList = model.yearsMap.values();
switch (ui->cb_replaceType->currentIndex()) {
case 0:
loadDataShow();
break;
case 1:
loadWeekShow();
break;
case 2:
loadMonthShow();
break;
case 3:
loadYearShow();
break;
case 4:
loadDayShow();
break;
case 5:
loadHourShow();
break;
default:
loadMonthShow();
break;
}
}
void DateReplaceEditor::applyStyleSheet()
{
QString styleSheet = R"(
QPushButton#closeBtn, QPushButton#checkBtn{
background-color: #E6F7FF;
border: 1px solid #87CEEB;
border-radius: 4px;
font-size: 24px;
color: #228B22;
}
QPushButton#closeBtn:hover,QPushButton#checkBtn:hover{
background-color: #D1E9FF;
}
QPushButton#closeBtn:pressed,QPushButton#checkBtn:pressed{
background-color: #BAE7FF;
}
QPushButton {
background-color: #5396C1;
color: #ffffff;
border: 1px solid #000000;
border-radius: 3px;
font-size: 18px;
font-weight:500;
width: 180px;
height: 90px;
}
QPushButton:hover {
background-color: #5396C1;
}
QPushButton:disabled {
background-color: #7C828E;
color: #606060;
border-color: #808080;
}
QComboBox {
border: 1px solid #000000;
border-radius: 3px;
font-size: 14px;
width: 180px;
height: 90px;
padding-left: 10px; /* 文字左边距,避免紧贴边缘 */
}
/* 下拉箭头区域 */
QComboBox::drop-down {
border: 1px solid #333333;
border-radius: 3px;
width: 30px; /* 箭头区域宽度 */
background-color: #5396C1;
}
/* 下拉箭头图标 */
QComboBox::down-arrow {
image: url(image/down_white.png);
width: 16px; /* 图标显示宽度 */
height: 16px; /* 图标显示高度 */
}
/* 悬停状态 */
QComboBox:hover {
background-color: #efefef;
}
// 下拉框
QComboBox QAbstractItemView {
border: 1px solid #000000;
border-radius: 3px;
font-size: 14px;
selection-background-color: #5396C1; /* 选中项背景色(稍深) */
selection-color: #ffffff;
}
)";
setStyleSheet(styleSheet);
}
void DateReplaceEditor::init()
{
connect(ui->lineEdit_Replace1, &QLineEdit::textChanged, std::bind(&DateReplaceEditor::onLineEditReplaceChanged, this, 0, std::placeholders::_1));
connect(ui->lineEdit_Replace2, &QLineEdit::textChanged, std::bind(&DateReplaceEditor::onLineEditReplaceChanged, this, 1, std::placeholders::_1));
connect(ui->lineEdit_Replace3, &QLineEdit::textChanged, std::bind(&DateReplaceEditor::onLineEditReplaceChanged, this, 2, std::placeholders::_1));
connect(ui->lineEdit_Replace4, &QLineEdit::textChanged, std::bind(&DateReplaceEditor::onLineEditReplaceChanged, this, 3, std::placeholders::_1));
}
void DateReplaceEditor::initReplaceValue()
{
monthList.clear();
for (int i = 1; i <= 12; ++i) {
monthList.append(QString("%1").arg(i, 2, 10, QChar('0')));
}
dataList.clear();
dataList << "0" << "1" << "2" << "3" << "4" << "5" << "6" << "7"
<< "8" << "9" << "A" << "B" << "C" << "D" << "E" << "F";
weekList.clear();
weekList << "MON" << "TUE" << "WED" << "THU" << "FRI" << "SAT" << "SUN";
yearList.clear();
yearInitList.clear();
int startYear = QDate::currentDate().year();
for (int i = 0; i < 16; ++i) {
yearList << QString::number(startYear + i);
yearInitList << startYear + i;
}
dayList.clear();
for (int i = 1; i <= 31; ++i) {
dayList.append(QString("%1").arg(i, 2, 10, QChar('0')));
}
hourList.clear();
for (int i = 0; i <= 23; ++i) {
hourList.append(QString("%1").arg(i, 2, 10, QChar('0')));
}
currPage = 0;
if(ui->cb_replaceType->currentIndex() == 2)
loadMonthShow();
else if(ui->cb_replaceType->currentIndex() == 0)
loadDataShow();
else if(ui->cb_replaceType->currentIndex() == 1)
loadWeekShow();
else if(ui->cb_replaceType->currentIndex() == 3)
loadYearShow();
else if(ui->cb_replaceType->currentIndex() == 4)
loadDayShow();
else if(ui->cb_replaceType->currentIndex() == 5)
loadHourShow();
}
void DateReplaceEditor::on_cb_replaceType_currentIndexChanged(int index)
{
currPage = 0;
initShowLineEdit();
if(index == 0){
loadDataShow();
}else if(index == 1){
loadWeekShow();
}else if(index == 2){
loadMonthShow();
}else if(index == 3){
loadYearShow();
}else if(index == 4){
loadDayShow();
}else if(index == 5){
loadHourShow();
}
}
void DateReplaceEditor::loadMonthShow()
{
initShowLineEdit();
if(currPage > 2)
currPage = 2;
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<monthList.size());i++){
QString strObject = QString("lineEditName") + QString::number(objectIndex);
QLineEdit *lineEdit = this->findChild<QLineEdit*>(strObject);
if(lineEdit)
lineEdit->setText(QString::number(i+1));
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2) {
auto b = lineEdit2->blockSignals(true);
lineEdit2->setText(monthList.at(i));
lineEdit2->blockSignals(b);
}
objectIndex++;
}
}
void DateReplaceEditor::loadDataShow()
{
initShowLineEdit();
if(currPage > 3)
currPage = 3;
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<dataList.size());i++){
QString strObject = QString("lineEditName") + QString::number(objectIndex);
QLineEdit *lineEdit = this->findChild<QLineEdit*>(strObject);
if(lineEdit)
lineEdit->setText(QString::number(i));
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2) {
auto b = lineEdit2->blockSignals(true);
lineEdit2->setText(dataList.at(i));
lineEdit2->blockSignals(b);
}
objectIndex++;
}
}
void DateReplaceEditor::loadWeekShow()
{
initShowLineEdit();
if(currPage > 1)
currPage = 1;
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<weekList.size());i++){
QString strObject = QString("lineEditName") + QString::number(objectIndex);
QLineEdit *lineEdit = this->findChild<QLineEdit*>(strObject);
if(lineEdit)
lineEdit->setText(QString::number(i+1));
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2) {
auto b = lineEdit2->blockSignals(true);
lineEdit2->setText(weekList.at(i));
lineEdit2->blockSignals(b);
}
objectIndex++;
}
}
void DateReplaceEditor::loadYearShow()
{
initShowLineEdit();
if(currPage > 3)
currPage = 3;
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<yearList.size());i++){
QString strObject = QString("lineEditName") + QString::number(objectIndex);
QLineEdit *lineEdit = this->findChild<QLineEdit*>(strObject);
if(lineEdit && i<yearInitList.size())
lineEdit->setText(QString::number(yearInitList.at(i)));
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2) {
auto b = lineEdit2->blockSignals(true);
lineEdit2->setText(yearList.at(i));
lineEdit2->blockSignals(b);
}
objectIndex++;
}
}
void DateReplaceEditor::loadDayShow()
{
initShowLineEdit();
if(currPage > 7)
currPage = 7;
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<dayList.size());i++){
QString strObject = QString("lineEditName") + QString::number(objectIndex);
QLineEdit *lineEdit = this->findChild<QLineEdit*>(strObject);
if(lineEdit)
lineEdit->setText(QString::number(i+1));
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2) {
auto b = lineEdit2->blockSignals(true);
lineEdit2->setText(dayList.at(i));
lineEdit2->blockSignals(b);
}
objectIndex++;
}
}
void DateReplaceEditor::loadHourShow()
{
initShowLineEdit();
if(currPage > 5)
currPage = 5;
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<hourList.size());i++){
QString strObject = QString("lineEditName") + QString::number(objectIndex);
QLineEdit *lineEdit = this->findChild<QLineEdit*>(strObject);
if(lineEdit)
lineEdit->setText(QString::number(i));
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2) {
auto b = lineEdit2->blockSignals(true);
lineEdit2->setText(hourList.at(i));
lineEdit2->blockSignals(b);
}
objectIndex++;
}
}
void DateReplaceEditor::getMonthValue()
{
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<monthList.size());i++){
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2)
monthList[i] = lineEdit2->text();
objectIndex++;
}
}
void DateReplaceEditor::getYearValue()
{
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<yearList.size());i++){
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2)
yearList[i] = lineEdit2->text();
objectIndex++;
}
}
void DateReplaceEditor::getDayValue()
{
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<dayList.size());i++){
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2)
dayList[i] = lineEdit2->text();
objectIndex++;
}
}
void DateReplaceEditor::getHourValue()
{
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<hourList.size());i++){
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2)
hourList[i] = lineEdit2->text();
objectIndex++;
}
}
void DateReplaceEditor::getWeekValue()
{
int objectIndex = 1;
for(int i=currPage*4;(i<(currPage+1)*4)&&(i<weekList.size());i++){
QString strObject2 = QString("lineEdit_Replace") + QString::number(objectIndex);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2)
weekList[i] = lineEdit2->text();
objectIndex++;
}
}
void DateReplaceEditor::on_btnUP_clicked()
{
if(currPage < 1)
return;
currPage = currPage - 1;
if(ui->cb_replaceType->currentIndex() == 2){
loadMonthShow();
}else if(ui->cb_replaceType->currentIndex() == 0){
loadDataShow();
}else if(ui->cb_replaceType->currentIndex() == 1){
loadWeekShow();
}else if(ui->cb_replaceType->currentIndex() == 3){
loadYearShow();
}else if(ui->cb_replaceType->currentIndex() == 4){
loadDayShow();
}else if(ui->cb_replaceType->currentIndex() == 5){
loadHourShow();
}
}
void DateReplaceEditor::on_btnDown_clicked()
{
initShowLineEdit();
int currentIndex = ui->cb_replaceType->currentIndex();
if (currentIndex == 2) {
if (currPage < 2) {
currPage++;
}
loadMonthShow();
return;
}
if (currentIndex == 0) {
if (currPage < 3) {
currPage++;
}
loadDataShow();
return;
}
if(currentIndex == 1){
if(currPage < 1){
currPage++;
}
loadWeekShow();
return;
}
if(currentIndex == 3){
if(currPage < 3){
currPage++;
}
loadYearShow();
return;
}
if(currentIndex == 4){
if(currPage < 7){
currPage++;
}
loadDayShow();
return;
}
if(currentIndex == 5){
if(currPage < 5){
currPage++;
}
loadHourShow();
return;
}
}
void DateReplaceEditor::initShowLineEdit()
{
for(int i=1;i<=4;i++){
QString strObject = QString("lineEditName") + QString::number(i);
QLineEdit *lineEdit = this->findChild<QLineEdit*>(strObject);
if(lineEdit)
lineEdit->setText("");
QString strObject2 = QString("lineEdit_Replace") + QString::number(i);
QLineEdit *lineEdit2 = this->findChild<QLineEdit*>(strObject2);
if(lineEdit2) {
auto b = lineEdit2->blockSignals(true);
lineEdit2->setText("");
lineEdit2->blockSignals(b);
}
}
}
void DateReplaceEditor::on_btnPreSetValue_clicked()
{
if(ui->cb_replaceType->currentIndex() == 2){
getMonthValue();
vartypeR = vartypeR | 1<<2;
QMap<int,QString> monthMap;
for(int i=0;i<monthList.size();i++){
monthMap.insert(i+1,monthList.at(i));
}
replaceValueMap.insert(2,monthMap);
}
else if(ui->cb_replaceType->currentIndex() == 3){
getYearValue();
vartypeR = vartypeR | 1<<3;
QMap<int,QString> yearMap;
for(int i=0;i<yearList.size()&&i<yearInitList.size();i++){
yearMap.insert(yearInitList.at(i),yearList.at(i));
}
replaceValueMap.insert(3,yearMap);
}
else if(ui->cb_replaceType->currentIndex() == 4){
getDayValue();
vartypeR = vartypeR | 1<<4;
QMap<int,QString> dayMap;
for(int i=0;i<dayList.size();i++){
dayMap.insert(i+1,dayList.at(i));
}
replaceValueMap.insert(4,dayMap);
}
else if(ui->cb_replaceType->currentIndex() == 5){
getHourValue();
vartypeR = vartypeR | 1<<5;
QMap<int,QString> hourMap;
for(int i=0;i<hourList.size();i++){
hourMap.insert(i,hourList.at(i));
}
replaceValueMap.insert(5,hourMap);
}
else if(ui->cb_replaceType->currentIndex() == 1){
getWeekValue();
vartypeR = vartypeR | 1<<1;
QMap<int,QString> weekMap;
for(int i=0;i<weekList.size();i++){
weekMap.insert(i+1,weekList.at(i));
}
replaceValueMap.insert(1,weekMap);
}
}
void DateReplaceEditor::onLineEditReplaceChanged(int i, QString txt)
{
int mapIdx = currPage * 4 + i;
switch(ui->cb_replaceType->currentIndex()) {
case 0:
if (mapIdx < dataList.size()) dataList[mapIdx] = txt;
break;
case 1:
if (mapIdx < weekList.size()) weekList[mapIdx] = txt;
break;
case 2:
if (mapIdx < monthList.size()) monthList[mapIdx] = txt;
break;
case 3:
if (mapIdx < yearList.size()) yearList[mapIdx] = txt;
break;
case 4:
if (mapIdx < dayList.size()) dayList[mapIdx] = txt;
break;
case 5:
if (mapIdx < hourList.size()) hourList[mapIdx] = txt;
break;
default:
break;
}
}
+66
View File
@@ -0,0 +1,66 @@
#ifndef DATEREPLACEEDITOR_H
#define DATEREPLACEEDITOR_H
#include <QWidget>
#include <QStringList>
#include <QList>
#include "ViewModels.h"
class QLineEdit;
namespace Ui {
class DateReplaceEditor;
}
class DateReplaceEditor : public QWidget
{
Q_OBJECT
public:
explicit DateReplaceEditor(QWidget *parent = nullptr);
~DateReplaceEditor();
DateItemModel dateModel();
void setDateModel(const DateItemModel& model);
void init();
void initReplaceValue();
void initShowLineEdit();
void loadMonthShow();
void loadDataShow();
void loadWeekShow();
void loadYearShow();
void loadDayShow();
void loadHourShow();
void getMonthValue();
void getYearValue();
void getHourValue();
void getWeekValue();
void getDayValue();
private slots:
void on_cb_replaceType_currentIndexChanged(int index);
void on_btnUP_clicked();
void on_btnDown_clicked();
void on_btnPreSetValue_clicked();
void onLineEditReplaceChanged(int i, QString txt);
private:
void applyStyleSheet();
Ui::DateReplaceEditor *ui;
int currPage = 0;
QStringList monthList;
QStringList dataList;
QStringList weekList;
QStringList yearList;
QList<int> yearInitList;
QStringList dayList;
QStringList hourList;
};
#endif // DATEREPLACEEDITOR_H
+307
View File
@@ -0,0 +1,307 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DateReplaceEditor</class>
<widget class="QWidget" name="DateReplaceEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>661</width>
<height>371</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton#closeBtn, QPushButton#checkBtn{
background-color: #E6F7FF;
border: 1px solid #87CEEB;
border-radius: 4px;
font-size: 24px;
color: #228B22;
}
QPushButton#closeBtn:hover,QPushButton#checkBtn:hover{
background-color: #D1E9FF;
}
QPushButton#closeBtn:pressed,QPushButton#checkBtn:pressed{
background-color: #BAE7FF;
}
QPushButton {
background-color: #5396C1;
color: #ffffff;
border: 1px solid #000000;
border-radius: 3px;
font-size: 18px;
font-weight:500;
width: 180px;
height: 90px;
}
QPushButton:hover {
background-color: #5396C1;
}
QPushButton:disabled {
background-color: #7C828E;
color: #606060;
border-color: #808080;
}
QComboBox {
border: 1px solid #000000;
border-radius: 3px;
font-size: 14px;
width: 180px;
height: 90px;
padding-left: 10px; /* 文字左边距,避免紧贴边缘 */
}
/* 下拉箭头区域 */
QComboBox::drop-down {
border: 1px solid #333333;
border-radius: 3px;
width: 30px; /* 箭头区域宽度 */
background-color: #5396C1;
}
/* 下拉箭头图标 */
QComboBox::down-arrow {
image: url(image/down_white.png);
width: 16px; /* 图标显示宽度 */
height: 16px; /* 图标显示高度 */
}
/* 悬停状态 */
QComboBox:hover {
background-color: #efefef;
}
// 下拉框
QComboBox QAbstractItemView {
border: 1px solid #000000;
border-radius: 3px;
font-size: 14px;
selection-background-color: #5396C1; /* 选中项背景色(稍深) */
selection-color: #ffffff;
}
</string>
</property>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>70</x>
<y>100</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>名称</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEditName1">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>80</x>
<y>130</y>
<width>113</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="lineEditName2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>80</x>
<y>170</y>
<width>113</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="lineEditName3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>80</x>
<y>210</y>
<width>113</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="lineEditName4">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>80</x>
<y>250</y>
<width>113</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="cb_replaceType">
<property name="geometry">
<rect>
<x>280</x>
<y>20</y>
<width>181</width>
<height>35</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>
<item>
<property name="text">
<string>天数</string>
</property>
</item>
<item>
<property name="text">
<string>小时</string>
</property>
</item>
<item>
<property name="text">
<string>Meridiem</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>220</x>
<y>30</y>
<width>50</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>类型</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>240</x>
<y>100</y>
<width>51</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>代替</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_Replace1">
<property name="geometry">
<rect>
<x>250</x>
<y>130</y>
<width>231</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_Replace2">
<property name="geometry">
<rect>
<x>250</x>
<y>170</y>
<width>231</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_Replace4">
<property name="geometry">
<rect>
<x>250</x>
<y>250</y>
<width>231</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_Replace3">
<property name="geometry">
<rect>
<x>250</x>
<y>210</y>
<width>231</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="btnUP">
<property name="geometry">
<rect>
<x>530</x>
<y>130</y>
<width>61</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>上</string>
</property>
</widget>
<widget class="QPushButton" name="btnDown">
<property name="geometry">
<rect>
<x>530</x>
<y>210</y>
<width>61</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>下</string>
</property>
</widget>
<widget class="QPushButton" name="btnPreSetValue">
<property name="geometry">
<rect>
<x>80</x>
<y>310</y>
<width>111</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>预设值</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
+110
View File
@@ -0,0 +1,110 @@
#include "ItemGeneralSettings.h"
#include "ui_ItemGeneralSettings.h"
#include <QDebug>
ItemGeneralSettings::ItemGeneralSettings(QWidget *parent) :
QWidget(parent),
ui(new Ui::ItemGeneralSettings)
{
ui->setupUi(this);
m_directionButtonGroup.addButton(ui->normalRBtn, NORMAL);
m_directionButtonGroup.addButton(ui->verMirrorRBtn, MIRROR_V);
m_directionButtonGroup.addButton(ui->horMirrorRBtn, MIRROR_H);
m_directionButtonGroup.addButton(ui->mirrorRBtn, MIRROR_VH);
m_directionButtonGroup.addButton(ui->m90NHorRBtn, MIRROR_H_R270);
m_directionButtonGroup.addButton(ui->a90RBtn, R90);
m_directionButtonGroup.addButton(ui->m90RBtn, R270);
m_directionButtonGroup.addButton(ui->m90NVerRBtn, MIRROR_V_R270);
connect(&m_directionButtonGroup, static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked),
this, &ItemGeneralSettings::ondirectionChanged);
}
ItemGeneralSettings::~ItemGeneralSettings()
{
delete ui;
}
void ItemGeneralSettings::edit(PicTextItem *item)
{
m_currItem = item;
if(!m_currItem) {
ui->boldSpinBox->setValue(ui->boldSpinBox->minimum());
ui->txtSpanSpinBox->setValue(ui->txtSpanSpinBox->minimum());
ui->normalRBtn->setChecked(true);
ui->invertCheckBox->setChecked(false);
ui->previewWidget->setImg(QImage());
return;
}
auto b = ui->boldSpinBox->blockSignals(true);
ui->boldSpinBox->setValue(item->boldMultiple());
ui->boldSpinBox->blockSignals(b);
b = ui->txtSpanSpinBox->blockSignals(true);
ui->txtSpanSpinBox->setValue(item->letterSpace());
ui->txtSpanSpinBox->blockSignals(b);
auto dirBtn = m_directionButtonGroup.button(item->direction());
b = dirBtn->blockSignals(true);
dirBtn->setChecked(true);
dirBtn->blockSignals(b);
b = ui->invertCheckBox->blockSignals(true);
ui->invertCheckBox->setChecked(item->colorReversal());
ui->invertCheckBox->blockSignals(b);
// 文字、日期、轮班可调字符间距
// 计数器类的字符间距由 @see CounterVarSet 单独调整
switch(item->sourceType()) {
case SourceType::TEXT:
case SourceType::DATETIME:
case SourceType::SCHEDULE_SHIFT:
ui->letterSpacePanel->setVisible(true);
break;
case SourceType::UNKNOWN:
default:
ui->letterSpacePanel->setVisible(false);
break;
}
ui->previewWidget->setImg(m_currItem->preview());
}
void ItemGeneralSettings::ondirectionChanged(int dir)
{
if(!m_currItem) {
return;
}
m_currItem->setDirection(ItemDirectionType(dir));
m_currItem->applyModify();
ui->previewWidget->setImg(m_currItem->preview());
}
void ItemGeneralSettings::onBoldSpinBoxValueChanged(int multiple)
{
if(m_currItem) {
m_currItem->setBoldMultiple(multiple);
m_currItem->applyModify();
ui->previewWidget->setImg(m_currItem->preview());
}
}
void ItemGeneralSettings::onLetterSpaceSpinBoxChanged(int space)
{
if(m_currItem) {
m_currItem->setLetterSpace(space);
m_currItem->applyModify();
ui->previewWidget->setImg(m_currItem->preview());
}
}
void ItemGeneralSettings::onColorReversalCheckBoxChecked(bool b)
{
if(m_currItem) {
m_currItem->setColorReversal(b);
m_currItem->applyModify();
ui->previewWidget->setImg(m_currItem->preview());
}
}
+39
View File
@@ -0,0 +1,39 @@
#ifndef ITEMGENERALSETTINGS_H
#define ITEMGENERALSETTINGS_H
#include <QWidget>
#include <QButtonGroup>
#include "pictextitem.h"
#include <QPainter>
namespace Ui {
class ItemGeneralSettings;
}
class ItemGeneralSettings : public QWidget
{
Q_OBJECT
public:
explicit ItemGeneralSettings(QWidget *parent = nullptr);
~ItemGeneralSettings();
void edit(PicTextItem* item);
PicTextItem* currentItem() { return m_currItem; }
private slots:
void ondirectionChanged(int dir);
void onBoldSpinBoxValueChanged(int multiple);
void onLetterSpaceSpinBoxChanged(int space);
void onColorReversalCheckBoxChecked(bool b);
private:
Ui::ItemGeneralSettings *ui;
QButtonGroup m_directionButtonGroup;
PicTextItem* m_currItem = nullptr;
QPainter m_painter;
};
#endif // ITEMGENERALSETTINGS_H
+703
View File
@@ -0,0 +1,703 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ItemGeneralSettings</class>
<widget class="QWidget" name="ItemGeneralSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>794</width>
<height>472</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true"> QPushButton {
background-color: #5396C1;
color: #ffffff;
border: 1px solid #000000;
border-radius: 3px;
font-size: 18px;
font-weight:500;
width: 180px;
height: 90px;
}
QPushButton:hover {
background-color: #5396C1;
}
QPushButton:disabled {
background-color: #7C828E;
color: #606060;
border-color: #808080;
}</string>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>20</y>
<width>71</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>反差</string>
</property>
<property name="buddy">
<cstring>densitySpinBox</cstring>
</property>
</widget>
<widget class="QSpinBox" name="counterIDSpinBox">
<property name="geometry">
<rect>
<x>320</x>
<y>390</y>
<width>48</width>
<height>26</height>
</rect>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
</widget>
<widget class="QPushButton" name="counterIdDownBtn">
<property name="geometry">
<rect>
<x>370</x>
<y>390</y>
<width>40</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>←</string>
</property>
</widget>
<widget class="QPushButton" name="counterIdUpBtn">
<property name="geometry">
<rect>
<x>410</x>
<y>390</y>
<width>40</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>→</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>320</x>
<y>30</y>
<width>71</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>粗体</string>
</property>
<property name="buddy">
<cstring>boldSpinBox</cstring>
</property>
</widget>
<widget class="QSpinBox" name="boldSpinBox">
<property name="geometry">
<rect>
<x>340</x>
<y>50</y>
<width>48</width>
<height>26</height>
</rect>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>8</number>
</property>
</widget>
<widget class="QPushButton" name="boldDownBtn">
<property name="geometry">
<rect>
<x>390</x>
<y>50</y>
<width>40</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>←</string>
</property>
</widget>
<widget class="QPushButton" name="boldUpBtn">
<property name="geometry">
<rect>
<x>430</x>
<y>50</y>
<width>40</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>→</string>
</property>
</widget>
<widget class="QCheckBox" name="invertCheckBox">
<property name="geometry">
<rect>
<x>40</x>
<y>100</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>颠倒</string>
</property>
</widget>
<widget class="QCheckBox" name="alternateCheckBox">
<property name="geometry">
<rect>
<x>40</x>
<y>150</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>交替</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>320</x>
<y>90</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>定向</string>
</property>
</widget>
<widget class="QRadioButton" name="normalRBtn">
<property name="geometry">
<rect>
<x>320</x>
<y>120</y>
<width>101</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/image/itemEditor/normal.png</normaloff>:/image/itemEditor/normal.png</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
<widget class="QRadioButton" name="verMirrorRBtn">
<property name="geometry">
<rect>
<x>430</x>
<y>120</y>
<width>101</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/image/itemEditor/verMirror.png</normaloff>:/image/itemEditor/verMirror.png</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
<widget class="QRadioButton" name="horMirrorRBtn">
<property name="geometry">
<rect>
<x>540</x>
<y>120</y>
<width>101</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/image/itemEditor/horMirror.png</normaloff>:/image/itemEditor/horMirror.png</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
<widget class="QRadioButton" name="m90NHorRBtn">
<property name="geometry">
<rect>
<x>320</x>
<y>160</y>
<width>61</width>
<height>81</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/image/itemEditor/m90_hor.png</normaloff>:/image/itemEditor/m90_hor.png</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
<widget class="QRadioButton" name="mirrorRBtn">
<property name="geometry">
<rect>
<x>640</x>
<y>120</y>
<width>101</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/image/itemEditor/mirror.png</normaloff>:/image/itemEditor/mirror.png</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
<widget class="QRadioButton" name="a90RBtn">
<property name="geometry">
<rect>
<x>430</x>
<y>160</y>
<width>61</width>
<height>81</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/image/itemEditor/a90.png</normaloff>:/image/itemEditor/a90.png</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
<widget class="QRadioButton" name="m90RBtn">
<property name="geometry">
<rect>
<x>540</x>
<y>160</y>
<width>61</width>
<height>81</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/image/itemEditor/m90.png</normaloff>:/image/itemEditor/m90.png</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
<widget class="QRadioButton" name="m90NVerRBtn">
<property name="geometry">
<rect>
<x>640</x>
<y>160</y>
<width>61</width>
<height>81</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/image/itemEditor/m90_ver.png</normaloff>:/image/itemEditor/m90_ver.png</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
<widget class="ImagePreviewer" name="previewWidget" native="true">
<property name="geometry">
<rect>
<x>50</x>
<y>240</y>
<width>661</width>
<height>111</height>
</rect>
</property>
</widget>
<widget class="QCheckBox" name="applyCounterCheckBox">
<property name="geometry">
<rect>
<x>300</x>
<y>360</y>
<width>161</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Print, when counter</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>460</x>
<y>390</y>
<width>101</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>计数器ID</string>
</property>
<property name="buddy">
<cstring>counterIDSpinBox</cstring>
</property>
</widget>
<widget class="QSpinBox" name="densitySpinBox">
<property name="geometry">
<rect>
<x>50</x>
<y>50</y>
<width>48</width>
<height>26</height>
</rect>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
</widget>
<widget class="QPushButton" name="densityDownBtn">
<property name="geometry">
<rect>
<x>100</x>
<y>50</y>
<width>40</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>←</string>
</property>
</widget>
<widget class="QPushButton" name="densityUpBtn">
<property name="geometry">
<rect>
<x>140</x>
<y>50</y>
<width>40</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>→</string>
</property>
</widget>
<widget class="QWidget" name="letterSpacePanel" native="true">
<property name="geometry">
<rect>
<x>530</x>
<y>30</y>
<width>181</width>
<height>61</height>
</rect>
</property>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>91</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>字符间距</string>
</property>
<property name="buddy">
<cstring>txtSpanSpinBox</cstring>
</property>
</widget>
<widget class="QSpinBox" name="txtSpanSpinBox">
<property name="geometry">
<rect>
<x>0</x>
<y>20</y>
<width>48</width>
<height>26</height>
</rect>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
</widget>
<widget class="QPushButton" name="txtSpanDownBtn">
<property name="geometry">
<rect>
<x>50</x>
<y>20</y>
<width>40</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>←</string>
</property>
</widget>
<widget class="QPushButton" name="txtSpanUpBtn">
<property name="geometry">
<rect>
<x>90</x>
<y>20</y>
<width>40</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>→</string>
</property>
</widget>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>ImagePreviewer</class>
<extends>QWidget</extends>
<header>imagepreviewer.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>invertCheckBox</tabstop>
<tabstop>densitySpinBox</tabstop>
<tabstop>densityDownBtn</tabstop>
<tabstop>densityUpBtn</tabstop>
<tabstop>boldSpinBox</tabstop>
<tabstop>boldDownBtn</tabstop>
<tabstop>boldUpBtn</tabstop>
<tabstop>txtSpanSpinBox</tabstop>
<tabstop>txtSpanDownBtn</tabstop>
<tabstop>txtSpanUpBtn</tabstop>
<tabstop>alternateCheckBox</tabstop>
<tabstop>normalRBtn</tabstop>
<tabstop>verMirrorRBtn</tabstop>
<tabstop>horMirrorRBtn</tabstop>
<tabstop>mirrorRBtn</tabstop>
<tabstop>m90NHorRBtn</tabstop>
<tabstop>a90RBtn</tabstop>
<tabstop>m90RBtn</tabstop>
<tabstop>m90NVerRBtn</tabstop>
<tabstop>applyCounterCheckBox</tabstop>
<tabstop>counterIDSpinBox</tabstop>
<tabstop>counterIdDownBtn</tabstop>
<tabstop>counterIdUpBtn</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>boldDownBtn</sender>
<signal>clicked()</signal>
<receiver>boldSpinBox</receiver>
<slot>stepDown()</slot>
<hints>
<hint type="sourcelabel">
<x>404</x>
<y>67</y>
</hint>
<hint type="destinationlabel">
<x>350</x>
<y>62</y>
</hint>
</hints>
</connection>
<connection>
<sender>boldUpBtn</sender>
<signal>clicked()</signal>
<receiver>boldSpinBox</receiver>
<slot>stepUp()</slot>
<hints>
<hint type="sourcelabel">
<x>456</x>
<y>67</y>
</hint>
<hint type="destinationlabel">
<x>352</x>
<y>68</y>
</hint>
</hints>
</connection>
<connection>
<sender>txtSpanDownBtn</sender>
<signal>clicked()</signal>
<receiver>txtSpanSpinBox</receiver>
<slot>stepDown()</slot>
<hints>
<hint type="sourcelabel">
<x>595</x>
<y>65</y>
</hint>
<hint type="destinationlabel">
<x>551</x>
<y>67</y>
</hint>
</hints>
</connection>
<connection>
<sender>txtSpanUpBtn</sender>
<signal>clicked()</signal>
<receiver>txtSpanSpinBox</receiver>
<slot>stepUp()</slot>
<hints>
<hint type="sourcelabel">
<x>633</x>
<y>69</y>
</hint>
<hint type="destinationlabel">
<x>553</x>
<y>66</y>
</hint>
</hints>
</connection>
<connection>
<sender>densityDownBtn</sender>
<signal>clicked()</signal>
<receiver>densitySpinBox</receiver>
<slot>stepDown()</slot>
<hints>
<hint type="sourcelabel">
<x>126</x>
<y>64</y>
</hint>
<hint type="destinationlabel">
<x>84</x>
<y>62</y>
</hint>
</hints>
</connection>
<connection>
<sender>densityUpBtn</sender>
<signal>clicked()</signal>
<receiver>densitySpinBox</receiver>
<slot>stepUp()</slot>
<hints>
<hint type="sourcelabel">
<x>170</x>
<y>67</y>
</hint>
<hint type="destinationlabel">
<x>76</x>
<y>67</y>
</hint>
</hints>
</connection>
<connection>
<sender>boldSpinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ItemGeneralSettings</receiver>
<slot>onBoldSpinBoxValueChanged(int)</slot>
<hints>
<hint type="sourcelabel">
<x>352</x>
<y>70</y>
</hint>
<hint type="destinationlabel">
<x>344</x>
<y>-33</y>
</hint>
</hints>
</connection>
<connection>
<sender>invertCheckBox</sender>
<signal>clicked(bool)</signal>
<receiver>ItemGeneralSettings</receiver>
<slot>onColorReversalCheckBoxChecked(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>49</x>
<y>139</y>
</hint>
<hint type="destinationlabel">
<x>-38</x>
<y>143</y>
</hint>
</hints>
</connection>
<connection>
<sender>txtSpanSpinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ItemGeneralSettings</receiver>
<slot>onLetterSpaceSpinBoxChanged(int)</slot>
<hints>
<hint type="sourcelabel">
<x>568</x>
<y>51</y>
</hint>
<hint type="destinationlabel">
<x>570</x>
<y>-17</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>onBoldSpinBoxValueChanged(int)</slot>
<slot>onLetterSpaceSpinBoxChanged(int)</slot>
<slot>onColorReversalCheckBoxChecked(bool)</slot>
</slots>
</ui>
+141
View File
@@ -0,0 +1,141 @@
#include "PicCounterItem.h"
#include <QDebug>
#include <QFont>
#include <QFontMetrics>
#include <QString>
#include <QHash>
QHash<QString, int> defCharWidthMap;
int charWidth(QFont font, int height) {
font.setLetterSpacing(QFont::AbsoluteSpacing, 0);
font.setPixelSize(height);
QFontMetrics fm(font);
return fm.horizontalAdvance("0123456789") / 10;
}
PicCounterItem::PicCounterItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type)
:PicTextItem(parent, scene, type)
{
}
QVariant PicCounterItem::source()
{
return PicTextItem::source();
}
void PicCounterItem::setSource(QVariant var)
{
PicTextItem::setSource(var);
setCounter(counterType(), digitalNum());
}
void PicCounterItem::setCounter(COUNTER_TYPE type, int digitalNum)
{
// 直接修改字体,生成新的HTML占位图
auto font = this->font();
QString fontname = font.family();
int pixelSize = 9;
QString numStr = "";
for(int i = fontname.length() - 1; i >= 0; --i) {
if(fontname[i].isDigit()) {
numStr.prepend(fontname[i]);
} else {
break;
}
}
if(!numStr.isEmpty()) {
pixelSize = numStr.toInt();
}
font.setFamily(fontname);
font.setPixelSize(pixelSize);
font.setWeight(false && (pixelSize<=16) ? QFont::Bold : QFont::Normal);
font.setLetterSpacing(QFont::AbsoluteSpacing, 0);
// font.setLetterSpacing(QFont::AbsoluteSpacing, 0);
QFontMetrics fontMetrics(font);
int width = (fontMetrics.horizontalAdvance("0123456789")) / 10;
int height = font.pixelSize();
width += letterSpace();
int varType1 = type;
if(fontname.contains("SerifL") || fontname.contains("serifl"))
varType1 = 20 + type;
else if(fontname.contains("SerifR") || fontname.contains("serifr"))
varType1 = 20 + type;
else if(fontname.contains("bangla"))
varType1 = 30 + type;
else if(fontname.contains("biyangF"))
varType1 = 50 + type;
else if(fontname.contains("Roman"))
varType1 = 60 + type;
setHtml(QString("<img src=\":/%1/%5/../image/digitalWidth%2.bmp\" height=\"%3\" width=\"%4\" style=\"vertical-align: bottom;\" />")
.arg(type).arg(false && (pixelSize<=16)?(digitalNum*100 + 75):digitalNum)
.arg(height + 1).arg(width*digitalNum).arg(varType1));
m_counterType = type;
m_digitalNum = digitalNum;
m_digitalImg = QImage(QString(":/%1/image/digitalWidth%2.bmp").arg(type).arg(digitalNum));
m_digitalImg = m_digitalImg.scaled(width*digitalNum, height + 1, Qt::IgnoreAspectRatio, Qt::FastTransformation);
applyModify();
qInfo() << "Counter item set to " << type ;
qInfo() << ">\tdigitalNum: " << digitalNum << ", font name: " << fontname << ", pixel size: " << pixelSize;
qInfo() << ">\tletterSpace: " << letterSpace() << "charRom width: " << digitalNum * width << " width: " << width;
}
int PicCounterItem::charWidth()
{
if(!m_charWidthMap.contains(font().family()))
return 0;
return m_charWidthMap[font().family()];
}
void PicCounterItem::setCharWidth(int width)
{
m_charWidthMap[font().family()] = width;
setCounter(counterType(), digitalNum());
}
QImage PicCounterItem::itemImage()
{
return m_digitalImg;
}
void PicCounterItem::setCustomAttrs(const QXmlStreamAttributes &attrs)
{
auto typeRef = attrs.value("counter_type");
auto digitalNumRef = attrs.value("digital_num");
bool ok = false;
int counterType = typeRef.toInt(&ok);
if(!ok || (counterType != COUNTER_TYPE_1 && COUNTER_TYPE_2 != counterType)) {
qWarning() << "Invalied counter type: " << counterType;
return;
}
ok = false;
int digitalNum = digitalNumRef.toInt(&ok);
if(!ok || digitalNum <= 0) {
qWarning() << "Invalied counter digital number: " << digitalNum;
return;
}
setCounter(static_cast<COUNTER_TYPE>(counterType), digitalNum);
qInfo() << "Loaded attrs from xml: " << " counter type: " << counterType << ", digitalNum: " << digitalNum;
}
void PicCounterItem::saveCustomAttrs(QXmlStreamAttributes &attrs)
{
attrs.append("counter_type", QString::number(counterType()));
attrs.append("digital_num", QString::number(digitalNum()));
qInfo() << "Set attrs to xml: " << " counter type: " << counterType() << ", digitalNum: " << digitalNum();
}
void PicCounterItem::letterSpaceChanged()
{
setSource(source());
}
+48
View File
@@ -0,0 +1,48 @@
#ifndef _PIC_COUNTER_ITEM_H_
#define _PIC_COUNTER_ITEM_H_
#include "pictextitem.h"
#include <QHash>
#include "ViewModels.h"
class PicCounterItem : public PicTextItem
{
public:
explicit PicCounterItem(QGraphicsItem *parent = 0, QGraphicsScene *scene = 0, const SourceType type = SourceType::COUNTER);
virtual QVariant source() override;
virtual void setSource(QVariant var) override;
void setCounter(COUNTER_TYPE type, int digitalNum);
COUNTER_TYPE counterType() const { return m_counterType; }
int digitalNum() const {return m_digitalNum; }
int charWidth();
void setCharWidth(int width);
protected:
/**
* @brief itemImage 子类可以重新实现该方法用于返回已经渲染好了的但未应用方向、水平拉伸的图像
* @return
* @remark
* 对图元进行方向、水平拉伸的步骤由 @see applyImgeTranslation 实现,因此子类不需要
*/
virtual QImage itemImage() override;
virtual void setCustomAttrs(const QXmlStreamAttributes& attrs);
virtual void saveCustomAttrs(QXmlStreamAttributes& attrs);
virtual void letterSpaceChanged() override;
private:
COUNTER_TYPE m_counterType;
int m_digitalNum;
QImage m_digitalImg;
QHash<QString, int> m_charWidthMap;
};
#endif // _PIC_COUNTER_ITEM_H_
+200
View File
@@ -0,0 +1,200 @@
#include "PicDateItem.h"
#include <QDebug>
#include <QRegExp>
#include "LogInfo.h"
PicDateItem::PicDateItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type)
:PicTextItem(parent, scene, type)
{
m_timer.setInterval(20);
connect(&m_timer, &QTimer::timeout, [this](){
updateDatetimeStr();
});
m_timer.start();
}
QVariant PicDateItem::source()
{
return m_model.datetimePattern;
}
void PicDateItem::setSource(QVariant var)
{
m_model.datetimePattern = var.toString();
if(m_model.datetimePattern.isEmpty())
return;
m_currDateTimeStr = generateDatetimeStr(QDateTime::currentDateTime());
applyModify();
}
void PicDateItem::setModel(DateItemModel model)
{
m_model = std::move(model);
setSource(m_model.datetimePattern);
}
const DateItemModel& PicDateItem::model() const
{
return m_model;
}
bool PicDateItem::updateDatetimeStr()
{
if (m_model.datetimePattern.isEmpty())
return false;
if(m_currDateTimeStr.isEmpty()) {
m_currDateTimeStr = generateDatetimeStr(QDateTime::currentDateTime());
applyModify();
return true;
}
auto now = QDateTime::currentDateTime();
auto str = generateDatetimeStr(now);
if(str == m_currDateTimeStr) {
return false;
}
m_currDateTimeStr = str;
applyModify();
return true;
}
void PicDateItem::setCustomAttrs(const QXmlStreamAttributes &attrs)
{
// 结构类似这样
// weeksMap = "MON<br>TUR<br>WED<br>TUE<br>THU<br>FRI<br>SAT<br>SUN"
// yearsMap = "2023<subbr>2023年<br>2024<subbr>2024年<br>2025<subbr>2025年"
auto m = DateItemModel();
m.dataMap = attrs.value("dataMap").toString().split("<br>");
m.daysMap = attrs.value("daysMap").toString().split("<br>");
m.hoursMap = attrs.value("hoursMap").toString().split("<br>");
m.monthsMap = attrs.value("monthsMap").toString().split("<br>");
m.weeksMap = attrs.value("weeksMap").toString().split("<br>");
auto yearsMap = attrs.value("yearsMap").toString().split("<br>");
for(auto it = yearsMap.begin(); it != yearsMap.end(); ++it) {
auto yearPair = it->split("<subbr>");
if(yearPair.size() == 2) {
m.yearsMap[yearPair[0].toInt()] = yearPair[1];
}
}
m.monthsOffset = attrs.value("monthsOffset").toInt();
m.daysOffset = attrs.value("daysOffset").toInt();
m.datetimePattern = attrs.value("datetimePattern").toString();
setModel(std::move(m));
}
void PicDateItem::saveCustomAttrs(QXmlStreamAttributes &attrs)
{
auto dataMap = m_model.dataMap.join("<br>");
auto daysMap = m_model.daysMap.join("<br>");
auto hoursMap = m_model.hoursMap.join("<br>");
auto monthsMap = m_model.monthsMap.join("<br>");
auto weeksMap = m_model.weeksMap.join("<br>");
QString yearsMap;
for(auto it = m_model.yearsMap.begin(); it != m_model.yearsMap.end(); ++it) {
yearsMap.append(QString("%1<subbr>%2<br>").arg(it.key()).arg(it.value()));
}
attrs.append("dataMap", dataMap);
attrs.append("daysMap", daysMap);
attrs.append("hoursMap", hoursMap);
attrs.append("monthsMap", monthsMap);
attrs.append("weeksMap", weeksMap);
attrs.append("yearsMap", yearsMap);
attrs.append("datetimePattern", m_model.datetimePattern);
attrs.append("monthsOffset", QString::number(m_model.monthsOffset));
attrs.append("daysOffset", QString::number(m_model.daysOffset));
}
QImage PicDateItem::itemImage()
{
if(m_model.datetimePattern.isEmpty())
return QImage();
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;
}
+42
View File
@@ -0,0 +1,42 @@
#ifndef PIC_DATE_ITEM_H
#define PIC_DATE_ITEM_H
#include "pictextitem.h"
#include <QDateTime>
#include <QTimer>
#include <QHash>
#include "ViewModels.h"
class PicDateItem : public PicTextItem
{
public:
PicDateItem(QGraphicsItem *parent = 0, QGraphicsScene *scene = 0, const SourceType type = SourceType::DATETIME);
virtual ~PicDateItem() {}
virtual QVariant source() override;
virtual void setSource(QVariant var) override;
void setModel(DateItemModel model);
const DateItemModel& model() const;
bool updateDatetimeStr();
protected:
virtual void setCustomAttrs(const QXmlStreamAttributes& attrs) override;
virtual void saveCustomAttrs(QXmlStreamAttributes& attrs) override;
virtual QImage itemImage() override;
private:
QString generateDatetimeStr(const QDateTime& datetime);
QTimer m_timer;
DateItemModel m_model;
QString m_currDateTimeStr;
};
#endif // PIC_DATE_ITEM_H
+48
View File
@@ -0,0 +1,48 @@
#include "PicImageItem.h"
PicImageItem::PicImageItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type)
:PicTextItem(parent, scene, type)
{
}
QVariant PicImageItem::source()
{
return m_imgPath;
}
void PicImageItem::setSource(QVariant var)
{
QImage img(var.toString());
if(img.isNull())
return;
m_img = img;
m_imgPath = var.toString();
applyModify();
}
QImage PicImageItem::itemImage()
{
return m_img;
}
void PicImageItem::setCustomAttrs(const QXmlStreamAttributes &attrs)
{
setSource(attrs.value("source").toString());
}
void PicImageItem::saveCustomAttrs(QXmlStreamAttributes &attrs)
{
attrs.append("source", source().toString());
}
void PicImageItem::colorReversalChanged()
{
// TODO:: 翻转图片
}
void PicImageItem::letterSpaceChanged()
{
// pass
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef PICIMAGEITEM_H
#define PICIMAGEITEM_H
#include "pictextitem.h"
class PicImageItem : public PicTextItem
{
Q_OBJECT
public:
explicit PicImageItem(QGraphicsItem *parent = 0, QGraphicsScene *scene = 0, const SourceType type = SourceType::IMAGE);
virtual QVariant source() override;
virtual void setSource(QVariant var) override;
protected:
virtual QImage itemImage() override;
virtual void setCustomAttrs(const QXmlStreamAttributes& attrs) override;
virtual void saveCustomAttrs(QXmlStreamAttributes& attrs) override;
virtual void colorReversalChanged() override;
virtual void letterSpaceChanged() override;
private:
QString m_imgPath;
QImage m_img;
};
#endif // PICIMAGEITEM_H
+118
View File
@@ -0,0 +1,118 @@
#include "PicScheduleShiftItem.h"
#include <algorithm>
#include "LogInfo.h"
PicScheduleShiftItem::PicScheduleShiftItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type)
:PicTextItem(parent, scene, type)
{
m_updateTimer.setInterval(20);
connect(&m_updateTimer, &QTimer::timeout, [this](){
updateScheduleName();
});
m_updateTimer.start();
}
QVariant PicScheduleShiftItem::source()
{
return QVariant();
}
void PicScheduleShiftItem::setSource(QVariant var)
{
m_currScheduleName = findScheduleName(QTime::currentTime());
applyModify();
}
const QVector<ScheduleModel>& PicScheduleShiftItem::schedules() const
{
return m_schedules;
}
void PicScheduleShiftItem::setSchedules(QVector<ScheduleModel> schedules)
{
m_schedules = std::move(schedules);
m_currScheduleName = findScheduleName(QTime::currentTime());
applyModify();
}
bool PicScheduleShiftItem::updateScheduleName()
{
if(m_currScheduleName.isEmpty()) {
m_currScheduleName = findScheduleName(QTime::currentTime());
applyModify();
return true;
}
auto str = findScheduleName(QTime::currentTime());
if(str == m_currScheduleName)
return false;
LogInfo::setRunStatusText("schedule old: " + str + ", old str: " + m_currScheduleName);
m_currScheduleName = str;
applyModify();
return true;
}
void PicScheduleShiftItem::setCustomAttrs(const QXmlStreamAttributes &attrs)
{
auto tableStr = attrs.value("schedule_table").toString();
if(tableStr.isEmpty())
return;
QVector<ScheduleModel> models;
auto table = tableStr.split("<br>");
models.reserve(table.size());
for(auto scheduleStr : table) {
auto pair = scheduleStr.split("<sub_br>");
if(pair.size() != 2)
continue;
ScheduleModel model;
model.startTime = QTime::fromString(pair[0], "hh:mm");
model.name = pair[1];
auto it = std::upper_bound(models.begin(), models.end(), model);
models.insert(it, model);
}
setSchedules(std::move(models));
}
void PicScheduleShiftItem::saveCustomAttrs(QXmlStreamAttributes &attrs)
{
QString tableStr;
for(auto& model : m_schedules) {
QString pair = model.startTime.toString("hh:mm") + "<sub_br>" + model.name;
tableStr += pair;
tableStr += "<br>";
}
attrs.append("schedule_table", tableStr);
}
QImage PicScheduleShiftItem::itemImage()
{
auto str = m_currScheduleName;
if(str.isEmpty()) {
QImage();
}
return strToImage(str);
}
QString PicScheduleShiftItem::findScheduleName(const QTime &time)
{
if(m_schedules.isEmpty())
return QString();
auto it = std::upper_bound(m_schedules.begin(), m_schedules.end(), time, [](const QTime& time, const ScheduleModel& value){
return value.startTime > time;
});
if(it == m_schedules.begin())
return m_schedules.rbegin()->name;
else
return std::prev(it)->name;
return QString();
}
+50
View File
@@ -0,0 +1,50 @@
#ifndef PICSCHEDULESHIFTITEM_H
#define PICSCHEDULESHIFTITEM_H
#include "pictextitem.h"
#include <QTime>
#include <QString>
#include <QTimer>
struct ScheduleModel
{
QTime startTime;
QString name;
};
static bool operator < (const ScheduleModel& l, const ScheduleModel& r) {
return l.startTime < r.startTime;
}
Q_DECLARE_METATYPE(ScheduleModel);
class PicScheduleShiftItem : public PicTextItem
{
public:
PicScheduleShiftItem(QGraphicsItem *parent = 0, QGraphicsScene *scene = 0, const SourceType type = SourceType::SCHEDULE_SHIFT);
virtual QVariant source();
virtual void setSource(QVariant var);
const QVector<ScheduleModel>& schedules() const;
void setSchedules(QVector<ScheduleModel> schedules);
bool updateScheduleName();
protected:
virtual void setCustomAttrs(const QXmlStreamAttributes& attrs) override;
virtual void saveCustomAttrs(QXmlStreamAttributes& attrs) override;
virtual QImage itemImage();
private:
QString findScheduleName(const QTime& time);
QVector<ScheduleModel> m_schedules;
QTimer m_updateTimer;
QString m_currScheduleName;
};
#endif // PICSCHEDULESHIFTITEM_H
+195
View File
@@ -0,0 +1,195 @@
#include "ScheduleShiftsEditor.h"
#include "ui_ScheduleShiftsEditor.h"
#include <QMouseEvent>
#include <QTimer>
#include <QModelIndex>
#include "PicScheduleShiftItem.h"
#include <QGridLayout>
#include <QDebug>
#include <QTableWidget>
#include <algorithm>
#include <QScrollBar>
ScheduleShiftsEditor::ScheduleShiftsEditor(QWidget *parent) :
QWidget(parent),
ui(new Ui::ScheduleShiftsEditor)
{
ui->setupUi(this);
m_generalSettings = new ItemGeneralSettings();
QGridLayout* layout = new QGridLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->setMargin(0);
layout->addWidget(m_generalSettings);
ui->generalSettingsTab->setLayout(layout);
// 禁用编辑
ui->tableSchedules->setEditTriggers(QTableWidget::NoEditTriggers);
ui->tableSchedules->setColumnWidth(0, 50);
ui->tableSchedules->setColumnWidth(1, 100);
ui->tableSchedules->setColumnWidth(2, 340);
ui->tableSchedules->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
ui->tableSchedules->horizontalHeader()->setVisible(true);
ui->tableSchedules->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->tableSchedules->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->tableSchedules->verticalScrollBar()->scroll(0, 0);
// ui->tableSchedules->setModel(m_viewModel);
connect(ui->tableSchedules, &QTableWidget::itemSelectionChanged, this, &ScheduleShiftsEditor::onTableSelectionChanged);
connect(ui->tableSchedules, &QTableWidget::currentItemChanged, this, [this](QTableWidgetItem*, QTableWidgetItem*){onTableSelectionChanged();});
connect(ui->tableSchedules, &QTableWidget::currentCellChanged, this, [this](int, int, int, int){onTableSelectionChanged();});
connect(ui->LineEditScheduleName, &QLineEdit::textChanged, this, &ScheduleShiftsEditor::btnAddEnbCheck);
connect(ui->timeEdit, &QTimeEdit::timeChanged, this, [this](const QTime&) {btnAddEnbCheck("");});
ui->btnAdd->setEnabled(false);
ui->btnRemove->setEnabled(false);
}
ScheduleShiftsEditor::~ScheduleShiftsEditor()
{
delete ui;
}
void ScheduleShiftsEditor::edit(PicScheduleShiftItem* item)
{
m_backup.clear();
m_generalSettings->edit(item);
if(item) {
item->saveAttrs(m_backup);
m_dataModel = item->schedules();
}
else {
m_dataModel.clear();
}
applyDataModel();
}
const QVector<ScheduleModel>& ScheduleShiftsEditor::dataModel() const
{
return m_dataModel;
}
PicScheduleShiftItem *ScheduleShiftsEditor::currEditItem()
{
return dynamic_cast<PicScheduleShiftItem*>(m_generalSettings->currentItem());
}
void ScheduleShiftsEditor::onBtnCloseClicked()
{
if(currEditItem()) {
currEditItem()->setAttrs(m_backup);
}
emit rejected();
}
void ScheduleShiftsEditor::onBtnAddClicked()
{
if(m_dataModel.size() >= 24) {
qWarning() << "The schedule shift has already reached the maximum number of 24 schedules.";
return;
}
auto t = ui->timeEdit->time();
auto b = std::binary_search(m_dataModel.begin(), m_dataModel.end(), ScheduleModel{t, QString()});
if(b) {
qWarning() << "The timestamp has already exist. " << t.toString("hh:mm");
return;
}
if(ui->LineEditScheduleName->text().isEmpty()) {
qWarning() << "The schedule name is empty.";
return;
}
ScheduleModel model;
model.startTime = t;
model.name = ui->LineEditScheduleName->text();
auto it = std::upper_bound(m_dataModel.begin(), m_dataModel.end(), model);
m_dataModel.insert(it, model);
qDebug() << "Schedule time: " << model.startTime.toString("hh:mm") << ", name: " << model.name << ", has added.";
applyDataModel();
ui->LineEditScheduleName->clear();
ui->btnRemove->setEnabled(false);
}
void ScheduleShiftsEditor::onBtnRemoveClicked()
{
if(ui->tableSchedules->currentRow() >= 0 && ui->tableSchedules->currentRow() < m_dataModel.size()) {
m_dataModel.remove(ui->tableSchedules->currentRow());
applyDataModel();
}
}
void ScheduleShiftsEditor::onTableSelectionChanged()
{
ui->btnRemove->setEnabled(ui->tableSchedules->currentRow() != -1);
}
void ScheduleShiftsEditor::btnAddEnbCheck(const QString &txt)
{
Q_UNUSED(txt);
ScheduleModel model {ui->timeEdit->time(), ""};
ui->btnAdd->setEnabled(!std::binary_search(m_dataModel.begin(), m_dataModel.end(), model) && !ui->LineEditScheduleName->text().isEmpty());
}
void ScheduleShiftsEditor::onBtnOkClicked()
{
emit accepted();
}
void ScheduleShiftsEditor::applyDataModel()
{
auto b = ui->tableSchedules->blockSignals(true);
ui->tableSchedules->clearContents();
ui->tableSchedules->setRowCount(m_dataModel.size());
for(int i = 0; i < m_dataModel.size(); ++i) {
QString time = m_dataModel[i].startTime.toString("hh:mm");
ui->tableSchedules->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));
ui->tableSchedules->setItem(i, 1, new QTableWidgetItem(time));
ui->tableSchedules->setItem(i, 2, new QTableWidgetItem(m_dataModel[i].name));
}
ui->tableSchedules->blockSignals(b);
auto txt = QString::number(24 - m_dataModel.size());
ui->LabNbRemains->setText(QString::number(24 - m_dataModel.size()));
}
void ScheduleShiftsEditor::applyStyleSheet()
{
// TODO:: 应用样式表
}
SelectedStyleTimeEdit::SelectedStyleTimeEdit(QWidget *parent)
:QTimeEdit(parent)
{
lineEdit()->installEventFilter(this);
}
SelectedStyleTimeEdit::~SelectedStyleTimeEdit()
{
lineEdit()->removeEventFilter(this);
}
bool SelectedStyleTimeEdit::eventFilter(QObject *obj, QEvent *event)
{
if (obj == lineEdit() && event->type() == QEvent::MouseButtonPress) {
// 先让父类处理(这会让内部状态更新)
bool result = QTimeEdit::eventFilter(obj, event);
// 延迟执行选中,确保currentSection已经更新
QTimer::singleShot(0, this, [this]() {
QDateTimeEdit::Section section = currentSection();
setSelectedSection(section);
});
return result;
}
return QTimeEdit::eventFilter(obj, event);
}
+66
View File
@@ -0,0 +1,66 @@
#ifndef SCHEDULESHIFTSEDITOR_H
#define SCHEDULESHIFTSEDITOR_H
#include <QWidget>
#include <QTime>
#include <QTimeEdit>
#include <QStandardItemModel>
#include "PicScheduleShiftItem.h"
#include "ItemGeneralSettings.h"
namespace Ui {
class ScheduleShiftsEditor;
}
/**
* @brief 重写实现以实现一个自定义的QTimeEdit组件,用于选择时间时,点击时间选择器的部分时,能够选中所选的部分,而不仅仅是移动光标
*/
class SelectedStyleTimeEdit : public QTimeEdit
{
Q_OBJECT
public:
SelectedStyleTimeEdit(QWidget *parent = nullptr);
virtual ~SelectedStyleTimeEdit();
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
};
class ScheduleShiftsEditor : public QWidget
{
Q_OBJECT
public:
explicit ScheduleShiftsEditor(QWidget *parent = nullptr);
~ScheduleShiftsEditor();
void edit(PicScheduleShiftItem* item);
const QVector<ScheduleModel>& dataModel() const;
PicScheduleShiftItem* currEditItem();
signals:
void accepted();
void rejected();
private slots:
void onBtnOkClicked();
void onBtnCloseClicked();
void onBtnAddClicked();
void onBtnRemoveClicked();
void onTableSelectionChanged();
void btnAddEnbCheck(const QString& txt);
private:
void applyDataModel();
void applyStyleSheet();
Ui::ScheduleShiftsEditor *ui;
QVector<ScheduleModel> m_dataModel;
ItemGeneralSettings* m_generalSettings = nullptr;
QXmlStreamAttributes m_backup;
};
#endif // SCHEDULESHIFTSEDITOR_H
+603
View File
@@ -0,0 +1,603 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ScheduleShiftsEditor</class>
<widget class="QWidget" name="ScheduleShiftsEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>550</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<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>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<property name="horizontalSpacing">
<number>22</number>
</property>
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="2" column="2">
<widget class="QPushButton" name="btnOk">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>62</width>
<height>42</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>40</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: #E6F7FF;
border: 1px solid #87CEEB;
border-radius: 4px;
min-width: 60px;
min-height: 40px;
font-size: 36px;
font-family: &quot;Ubuntu&quot;;
color: #228B22;
}
QPushButton:hover {
background-color: #D1E9FF;
}
QPushButton:pressed {
background-color: #BAE7FF;
}</string>
</property>
<property name="text">
<string>✓</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QPushButton" name="btnClose">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>62</width>
<height>42</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>40</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
background-color: #E6F7FF;
border: 1px solid #87CEEB;
border-radius: 4px;
min-width: 60px;
min-height: 40px;
font-size: 36px;
font-family: &quot;Ubuntu&quot;;
color: #228B22;
}
QPushButton:hover {
background-color: #D1E9FF;
}
QPushButton:pressed {
background-color: #BAE7FF;
}</string>
</property>
<property name="text">
<string>✕</string>
</property>
</widget>
</item>
<item row="2" column="0">
<spacer name="horizontalSpacer">
<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 row="1" column="0" colspan="4">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="generalSettingsTab">
<attribute name="title">
<string>整体设置</string>
</attribute>
</widget>
<widget class="QWidget" name="scheduleShiftsEditTab">
<property name="styleSheet">
<string notr="true"> QPushButton {
background-color: #5396C1;
color: #ffffff;
border: 1px solid #000000;
border-radius: 3px;
font-size: 18px;
font-weight:500;
width: 180px;
height: 90px;
}
QPushButton:hover {
background-color: #5396C1;
}
QPushButton:disabled {
background-color: #7C828E;
color: #606060;
border-color: #808080;
}</string>
</property>
<attribute name="title">
<string>班时编号</string>
</attribute>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>83</x>
<y>11</y>
<width>91</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>班时时间</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>370</x>
<y>11</y>
<width>81</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>班时编号</string>
</property>
</widget>
<widget class="QLineEdit" name="LineEditScheduleName">
<property name="geometry">
<rect>
<x>370</x>
<y>40</y>
<width>221</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QTableWidget" name="tableSchedules">
<property name="geometry">
<rect>
<x>20</x>
<y>90</y>
<width>491</width>
<height>351</height>
</rect>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="rowCount">
<number>3</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>25</number>
</attribute>
<row>
<property name="text">
<string>新建行</string>
</property>
</row>
<row>
<property name="text">
<string>新建行</string>
</property>
</row>
<row/>
<column>
<property name="text">
<string>标号</string>
</property>
<property name="textAlignment">
<set>AlignCenter</set>
</property>
</column>
<column>
<property name="text">
<string>班时时间</string>
</property>
</column>
<column>
<property name="text">
<string>班时编号</string>
</property>
</column>
<item row="0" column="0">
<property name="text">
<string>1</string>
</property>
<property name="textAlignment">
<set>AlignCenter</set>
</property>
</item>
<item row="0" column="1">
<property name="text">
<string>00:00</string>
</property>
</item>
<item row="0" column="2">
<property name="text">
<string>A</string>
</property>
</item>
<item row="1" column="0">
<property name="text">
<string>2</string>
</property>
<property name="textAlignment">
<set>AlignCenter</set>
</property>
</item>
<item row="1" column="1">
<property name="text">
<string>08:09</string>
</property>
</item>
<item row="1" column="2">
<property name="text">
<string>B</string>
</property>
</item>
<item row="2" column="0">
<property name="text">
<string>3</string>
</property>
<property name="textAlignment">
<set>AlignCenter</set>
</property>
</item>
<item row="2" column="1">
<property name="text">
<string>12:00</string>
</property>
</item>
<item row="2" column="2">
<property name="text">
<string>C</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>523</x>
<y>91</y>
<width>191</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>可选用的班次时间:</string>
</property>
</widget>
<widget class="QLabel" name="LabNbRemains">
<property name="geometry">
<rect>
<x>603</x>
<y>131</y>
<width>61</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>15</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(0, 193, 0);</string>
</property>
<property name="text">
<string>23</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>530</x>
<y>210</y>
<width>51</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>←</string>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>530</x>
<y>260</y>
<width>54</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>→</string>
</property>
</widget>
<widget class="QPushButton" name="btnAdd">
<property name="geometry">
<rect>
<x>600</x>
<y>210</y>
<width>101</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>添加</string>
</property>
</widget>
<widget class="QPushButton" name="btnRemove">
<property name="geometry">
<rect>
<x>600</x>
<y>260</y>
<width>101</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>移除</string>
</property>
</widget>
<widget class="SelectedStyleTimeEdit" name="timeEdit">
<property name="geometry">
<rect>
<x>80</x>
<y>40</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="showGroupSeparator" stdset="0">
<bool>false</bool>
</property>
<property name="minimumDate">
<date>
<year>2001</year>
<month>1</month>
<day>1</day>
</date>
</property>
<property name="maximumTime">
<time>
<hour>23</hour>
<minute>59</minute>
<second>0</second>
</time>
</property>
<property name="displayFormat">
<string>hh:mm</string>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
<property name="currentSectionIndex">
<number>0</number>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>170</x>
<y>40</y>
<width>31</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>←</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>200</x>
<y>40</y>
<width>31</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>→</string>
</property>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SelectedStyleTimeEdit</class>
<extends>QTimeEdit</extends>
<header>scene/ScheduleShiftsEditor.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>btnOk</sender>
<signal>clicked()</signal>
<receiver>ScheduleShiftsEditor</receiver>
<slot>onBtnOkClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>642</x>
<y>523</y>
</hint>
<hint type="destinationlabel">
<x>637</x>
<y>685</y>
</hint>
</hints>
</connection>
<connection>
<sender>btnClose</sender>
<signal>clicked()</signal>
<receiver>ScheduleShiftsEditor</receiver>
<slot>onBtnCloseClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>726</x>
<y>518</y>
</hint>
<hint type="destinationlabel">
<x>743</x>
<y>627</y>
</hint>
</hints>
</connection>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>timeEdit</receiver>
<slot>stepDown()</slot>
<hints>
<hint type="sourcelabel">
<x>196</x>
<y>82</y>
</hint>
<hint type="destinationlabel">
<x>140</x>
<y>80</y>
</hint>
</hints>
</connection>
<connection>
<sender>pushButton_2</sender>
<signal>clicked()</signal>
<receiver>timeEdit</receiver>
<slot>stepUp()</slot>
<hints>
<hint type="sourcelabel">
<x>231</x>
<y>82</y>
</hint>
<hint type="destinationlabel">
<x>143</x>
<y>81</y>
</hint>
</hints>
</connection>
<connection>
<sender>btnAdd</sender>
<signal>clicked()</signal>
<receiver>ScheduleShiftsEditor</receiver>
<slot>onBtnAddClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>652</x>
<y>255</y>
</hint>
<hint type="destinationlabel">
<x>866</x>
<y>267</y>
</hint>
</hints>
</connection>
<connection>
<sender>btnRemove</sender>
<signal>clicked()</signal>
<receiver>ScheduleShiftsEditor</receiver>
<slot>onBtnRemoveClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>667</x>
<y>306</y>
</hint>
<hint type="destinationlabel">
<x>864</x>
<y>297</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>onBtnOkClicked()</slot>
<slot>onBtnCloseClicked()</slot>
<slot>onBtnAddClicked()</slot>
<slot>onBtnRemoveClicked()</slot>
</slots>
</ui>
+56
View File
@@ -0,0 +1,56 @@
#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;
model.dataMap << "0" << "1" << "2" << "3" << "4" << "5" << "6" << "7"
<< "8" << "9" << "A" << "B" << "C" << "D" << "E" << "F";
for (int i = 1; i <= 31; ++i) {
model.daysMap.append(QString("%1").arg(i, 2, 10, QChar('0')));
}
for (int i = 1; i <= 12; ++i) {
model.monthsMap.append(QString("%1").arg(i, 2, 10, QChar('0')));
}
int startYear = QDate::currentDate().year();
for (int i = 0; i < 16; ++i) {
model.yearsMap.insert(startYear + i, QString::number(startYear + i));
}
model.weeksMap << "MON" << "TUE" << "WED" << "THU" << "FRI" << "SAT" << "SUN";
for (int i = 0; i <= 23; ++i) {
model.hoursMap.append(QString("%1").arg(i, 2, 10, QChar('0')));
}
return model;
}
+143
View File
@@ -0,0 +1,143 @@
#ifndef VIEWMODELS_H
#define VIEWMODELS_H
#include <QObject>
#include <QString>
#include <QDate>
#include <QSharedPointer>
#include "SysPara.h"
#include <QMap>
/**
* @brief 计数器类型
*
*/
enum COUNTER_TYPE {
COUNTER_TYPE_1 = 7,
COUNTER_TYPE_2 = 8,
};
/**
* @brief 计数器设置界面所用的视图模型
*
*/
struct CounterViewModel {
int counterType = 0; // 实际类型为 COUNTER_TYPE
int digitalNum = 0;
int letterSpace = 0;
int charWidth = 0; // 字符宽度,仅在 enbCustomCharWidth == true 时有意义
bool enbCustomCharWidth = false;
SysPara* m_sysPara = nullptr; // 计数器设置界面中还依赖此对象,所以先给它
};
Q_DECLARE_METATYPE(CounterViewModel);
/**
* @brief 日期设置界面所用的视图模型
*
*/
struct DateItemModel {
QString datetimePattern;
int monthsOffset = 0;
int daysOffset = 0;
QStringList dataMap; // unused
QStringList daysMap;
QStringList monthsMap;
QMap<int, QString> yearsMap;
QStringList weeksMap;
QStringList hoursMap;
static DateItemModel createDefaultReplaceModel();
};
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
+65
View File
@@ -0,0 +1,65 @@
#include "myview.h"
#include <QWheelEvent>
#include "picscene.h"
#include <QDebug>
MyView::MyView(QWidget *parent) :
QGraphicsView(parent)
{
zoomRatio = 1;
//setDragMode(QGraphicsView::ScrollHandDrag);//手型拖动
//setAlignment(Qt::AlignLeft | Qt::AlignTop);
//setFocusPolicy( Qt::NoFocus );
}
// static float a = 1.615;
static float a = 1.64;
void MyView::ZoomOut(void)
{
if(zoomRatio < 6)
{
zoomRatio++;
// scale(2,2);
scale(a,a);
}
}
void MyView::ZoomIn(void)
{
if(zoomRatio > 2)
{
zoomRatio--;
scale(1/a,1/a);
}
}
//void MyView::wheelEvent(QWheelEvent*event) //滚轮事件
//{
//// if(event->delta() > 0) //如果鼠标滚轮远离使用者,则delta()返回正值
//// scale(0.5,0.5); //视图缩放
//// else scale(2,2);
//}
//void MyView::mousePressEvent(QMouseEvent*event)
//{
//// rotate(90); //视图旋转顺时针90度
//}
void MyView::keyPressEvent(QKeyEvent *event)
{
//event->accept();
//parent()->event((QEvent*) event);
if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right || event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)
{
// 处理上下键事件
PicScene* picScene = dynamic_cast<PicScene*>(this->scene());
if(picScene)
{
picScene->keyPressEvent(event);
}
}
else
{
// 其他键事件交给父类处理
QGraphicsView::keyPressEvent(event);
}
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef MYVIEW_H
#define MYVIEW_H
#include <QGraphicsView>
class MyView : public QGraphicsView
{
Q_OBJECT
public:
explicit MyView(QWidget *parent = 0);
void ZoomOut(void);
void ZoomIn(void);
//char getzoomRatio(){return zoomRatio;}
private:
char zoomRatio;
signals:
public slots:
protected :
// void wheelEvent(QWheelEvent *event);
// void mousePressEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
};
#endif // MYVIEW_H
+38
View File
@@ -0,0 +1,38 @@
#include "piccodeitem.h"
PicCodeItem::PicCodeItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type)
:PicTextItem(parent, scene, type)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemIsSelectable);
setFlag(QGraphicsItem::ItemIsFocusable);
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
}
QVariant PicCodeItem::source()
{
return imagePath;
}
void PicCodeItem::setSource(QVariant var)
{
imagePath = var.toString();
applyModify();
}
QImage PicCodeItem::itemImage()
{
return QImage(imagePath);
}
void PicCodeItem::setCustomAttrs(const QXmlStreamAttributes &attrs)
{
imagePath = attrs.value("CodeImage").toString();
}
void PicCodeItem::saveCustomAttrs(QXmlStreamAttributes &attrs)
{
attrs.append("CodeImage", imagePath);
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef PICCODEITEM_H
#define PICCODEITEM_H
#include "pictextitem.h"
class PicCodeItem : public PicTextItem
{
public:
PicCodeItem(QGraphicsItem *parent = 0, QGraphicsScene *scene = 0,
const SourceType type = SourceType::CODE);
virtual ~PicCodeItem() {}
virtual QVariant source() override;
virtual void setSource(QVariant var) override;
protected:
/**
* @brief itemImage 子类可以重新实现该方法用于返回已经渲染好了的但未应用方向、水平拉伸的图像
* @return
* @remark
* 对图元进行方向、水平拉伸的步骤由 @see applyImgeTranslation 实现,因此子类不需要
*/
virtual QImage itemImage() override;
virtual void setCustomAttrs(const QXmlStreamAttributes& attrs);
virtual void saveCustomAttrs(QXmlStreamAttributes& attrs);
private:
// 保存图片的绝对路径
QString imagePath = "";
};
#endif // PICCODEITEM_H
+148
View File
@@ -0,0 +1,148 @@
#include "picscene.h"
#include <QDebug>
#include <QRectF>
#include <QPainter>
#include <QGraphicsView>
PicScene::PicScene(QObject *parent) :
QGraphicsScene(parent),IsdrawBackground(false),
currFocusItem(nullptr)
{
connect(this, &QGraphicsScene::focusItemChanged, this, &PicScene::onFocusItemChanged);
}
void PicScene::setMode(Mode mode)
{
myMode = mode;
}
void PicScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if (mouseEvent->button() != Qt::LeftButton)
return;
QGraphicsScene::mousePressEvent(mouseEvent);
}
//! [9]
//! [10]
void PicScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
update();//edit@12-12
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
//! [10]
//! [11]
void PicScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
//! [13]
//! [14]
bool PicScene::isItemChange(int type)
{
foreach (QGraphicsItem *item, selectedItems()) {
if (item->type() == type)
return true;
}
return false;
}
//! [14]
void PicScene::keyPressEvent(QKeyEvent *event)
{
QGraphicsScene::keyPressEvent(event);
}
//edit@12-09
void PicScene::drawBackground(QPainter *painter, const QRectF &rect)
{
QGraphicsScene::drawBackground(painter,rect);
if(IsdrawBackground)
{
QPen pen;
// 使用sceneRect()而不是参数rect,因为rect是由view设置的,其依赖于当前view的大小
const qreal left = sceneRect().left();
const qreal right = sceneRect().right();
const qreal top = sceneRect().top();
const qreal bottom = sceneRect().bottom();
const int step=1;
//pen.setColor(QColor(60,60,60));
pen.setColor(Qt::lightGray);
//pen.setColor(Qt::darkCyan);
pen.setWidth(0);
//pen.setStyle(Qt::DashLine);
painter->setPen(pen);
//绘制横线
//绘制Y轴正半轴
for(int i=0;i>=top;i-=step)
{
painter->drawLine(left,i,right,i);
}
//绘制Y轴负半轴
for(int i=0;i<=bottom;i+=step)
{
painter->drawLine(left,i,right,i);
}
//绘制竖线
//绘制X轴正半轴
for(int i=0;i<=right;i+=step)
{
painter->drawLine(i,top,i,bottom);
}
//绘制X轴负半轴
for(int i=0;i>=left;i-=step)
{
painter->drawLine(i,top,i,bottom);
}
//edit@12-11
pen.setColor(Qt::green);
painter->setPen(pen);
QRectF BoundingRect=this->itemsBoundingRect();
//BoundingRect.setHeight(32);
painter->drawRect(BoundingRect);
}
emit showTextWidthHeight();
}
//edit@12-09
void PicScene::setIsdrawBackground(bool newIsdrawBackground)
{
IsdrawBackground = newIsdrawBackground;
}
void PicScene::onFocusItemChanged(QGraphicsItem *newFocusItem, QGraphicsItem *oldFocusItem, Qt::FocusReason reason)
{
// 断开旧的连接
if(currFocusItem) {
disconnect(currFocusItem, &QGraphicsObject::xChanged, this, &PicScene::onFocusedItemPosChanged);
disconnect(currFocusItem, &QGraphicsObject::yChanged, this, &PicScene::onFocusedItemPosChanged);
}
// 只对对所有继承于QGraphicsObject的Item有效
// 仅有继承于QGraphicsObject的item实现了x,y changed信号
currFocusItem = dynamic_cast<QGraphicsObject*>(newFocusItem);
if(!currFocusItem){
// Nothing
return;
}
QPoint pos(currFocusItem->x(), currFocusItem->y());
emit focusedItemPosChanged(pos);
connect(currFocusItem, &QGraphicsObject::xChanged, this, &PicScene::onFocusedItemPosChanged);
connect(currFocusItem, &QGraphicsObject::yChanged, this, &PicScene::onFocusedItemPosChanged);
}
void PicScene::onFocusedItemPosChanged()
{
if(currFocusItem)
emit focusedItemPosChanged(currFocusItem->pos().toPoint());
}
+77
View File
@@ -0,0 +1,77 @@
#ifndef PICSCENE_H
#define PICSCENE_H
#include <QGraphicsScene>
#include "pictextitem.h"
#include <QGraphicsSceneMouseEvent>
#include <QPoint>
QT_BEGIN_NAMESPACE
class QGraphicsSceneMouseEvent;
class QMenu;
class QPointF;
class QGraphicsLineItem;
class QFont;
class QGraphicsTextItem;
class QColor;
QT_END_NAMESPACE
class PicScene : public QGraphicsScene
{
Q_OBJECT
public:
enum Mode { InsertItem, InsertLine, InsertText, InsertPic, MoveItem };
explicit PicScene(QObject *parent = 0);
QFont font() const
{ return myFont; }
QColor textColor() const
{ return myTextColor; }
QColor itemColor() const
{ return myItemColor; }
QColor lineColor() const
{ return myLineColor; }
void setLineColor(const QColor &color);
void setTextColor(const QColor &color);
void setItemColor(const QColor &color);
void setFont(const QFont &font);
void keyPressEvent(QKeyEvent *event);
public slots:
void setMode(Mode mode);
void setIsdrawBackground(bool newIsdrawBackground);
signals:
void textInserted(QGraphicsTextItem *item);
void itemSelected(QGraphicsItem *item);
void xmlContentChanged();
void showTextWidthHeight();
void adjustItemsPos();
void focusedItemPosChanged(QPoint p);
private slots:
void onFocusItemChanged(QGraphicsItem *newFocusItem, QGraphicsItem *oldFocusItem, Qt::FocusReason reason);
void onFocusedItemPosChanged();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
void drawBackground(QPainter *painter, const QRectF &rect);
private:
bool isItemChange(int type);
QMenu *myItemMenu;
Mode myMode;
bool leftButtonDown;
QPointF startPoint;
QGraphicsLineItem *line;
QFont myFont;
PicTextItem *textItem;
QColor myTextColor;
QColor myItemColor;
QColor myLineColor;
bool IsdrawBackground;
QGraphicsObject* currFocusItem;
};
#endif // PICSCENE_H
+443
View File
@@ -0,0 +1,443 @@
#include <QtGui>
#include "pictextitem.h"
#include "picscene.h"
#include <cmath>
#include <QPainter>
//#include "moveinput.h"
#include <QStyleOptionGraphicsItem>
//extern MoveInput* moveInput;
PicTextItem::PicTextItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType t) :
QGraphicsTextItem(parent), //edit@02-07
m_sourceType(t)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemIsSelectable);
setFlag(QGraphicsItem::ItemIsFocusable);
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
QFont f("Dinkie9");
// font.setFamily("wenquanyi");
// font.setPixelSize(5);
f.setLetterSpacing(QFont::AbsoluteSpacing, 1);
setFont(f);
document()->setDefaultStyleSheet("p { margin: 0; }");
document()->setDocumentMargin(0);
SpecialConditions = false;
CatchCnt1CurrValue = -1;
CatchCnt1StartValue = -1;
}
PicTextItem::~PicTextItem()
{
}
QVariant PicTextItem::source()
{
return m_source;
}
QImage clipImage(QImage img, const QRgb bg)
{
QRect clipRect;
for(int x = 0; x < img.width(); ++x) {
for(int y = 0; y < img.height(); ++y) {
auto rgb = img.pixel(x, y);
if(rgb != bg) {
clipRect.setLeft(x);
goto top;
}
}
}
top:
for(int y = 0; y < img.height(); ++y) {
for(int x = 0; x < img.width(); ++x) {
if(img.pixel(x, y) != bg) {
clipRect.setTop(y);
goto right;
}
}
}
right:
for(int x = img.width() - 1; x >= 0; --x) {
for(int y = 0; y < img.height(); ++y) {
if(img.pixel(x, y) != bg) {
clipRect.setRight(x + 1);
goto bottom;
}
}
}
bottom:
for(int y = img.height() - 1; y >= 0; --y) {
for(int x = 0; x < img.width(); ++x) {
if(img.pixel(x, y) != bg) {
clipRect.setBottom(y + 1);
goto end;
}
}
}
end:
QRect originRect = img.rect();
return img.copy(clipRect);
}
QImage PicTextItem::applyImgeTranslation(QImage img)
{
auto scaledWidth = boldMultiple() * img.width();
QImage ret = img.scaled(QSize(scaledWidth, img.height()));
switch(direction()) {
case NORMAL:
break;
case MIRROR_V:
ret = ret.mirrored(false, true);
break;
case MIRROR_H:
ret = ret.mirrored(true, false);
break;
case MIRROR_VH:
ret = ret.mirrored(true, true);
break;
case MIRROR_H_R270: {
QTransform trans;
trans.rotate(180, Qt::YAxis);
trans.rotate(270.0);
ret = ret.transformed(trans);
break;
}
case R90:
{
QTransform trans;
trans.rotate(90.0);
ret = ret.transformed(trans);
break;
}
case R270:
{
QTransform trans;
trans.rotate(270.0);
ret = ret.transformed(trans);
break;
}
case MIRROR_V_R270:
{
QTransform trans;
trans.rotate(180, Qt::XAxis);
trans.rotate(270.0);
ret = ret.transformed(trans);
break;
}
default:
break;
}
// TODOD:: 添加颜色翻转功能
return ret;
}
void PicTextItem::setSource(QVariant var)
{
m_source = var;
if(SourceType::TEXT != sourceType())
return;
m_untransImage = strToImage(m_source.toString());
applyModify();
}
int PicTextItem::setBoldMultiple(int multiple)
{
m_boldMultiple = multiple;
}
void PicTextItem::setDirection(ItemDirectionType dir)
{
m_direction = dir;
}
void PicTextItem::setColorReversal(bool b)
{
m_colorReversal = b;
colorReversalChanged();
}
void PicTextItem::setCustomFont(QString name)
{
auto newFont = QFont(name);
newFont.setLetterSpacing(QFont::AbsoluteSpacing, letterSpace());
newFont.setStyleStrategy(QFont::NoAntialias);
setFont(newFont);
setSource(source());
}
int PicTextItem::letterSpace()
{
return int(font().letterSpacing());
}
void PicTextItem::setLetterSpace(int space)
{
auto f = font();
f.setLetterSpacing(QFont::AbsoluteSpacing, space);
setFont(f);
letterSpaceChanged();
}
void PicTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
if(sourceType() == SourceType::UNKNOWN) {
QGraphicsTextItem::paint(painter, option, widget);
return;
}
painter->save();
auto r = option->rect;
painter->setFont(font());
painter->drawImage(r, m_itemImage);
if(isSelected()) {
painter->setPen("red");
painter->drawRect(r);
}
painter->restore();
}
QRectF PicTextItem::boundingRect() const
{
if(sourceType() == SourceType::UNKNOWN)
return QGraphicsTextItem::boundingRect();
const QRectF fr(0, 0, m_itemImage.width(), m_itemImage.height());
return fr;
}
QPainterPath PicTextItem::shape() const
{
QPainterPath path;
path.addRect(boundingRect());
return path;
}
void PicTextItem::setAttrs(const QXmlStreamAttributes &attrs)
{
auto dirRef = attrs.value("dir");
if(!dirRef.isEmpty()) {
bool ok = false;
auto d = dirRef.toInt(&ok);
if(ok)
setDirection((ItemDirectionType)d);
}
auto boldMultipleRef = attrs.value("boldMultiple");
if(!boldMultipleRef.isEmpty()) {
bool ok = false;
auto b = boldMultipleRef.toInt(&ok);
if(ok)
setBoldMultiple(b);
}
auto colorReversalRef = attrs.value("colorReversal");
if(!colorReversalRef.isEmpty()) {
auto s = colorReversalRef.toString().toLower();
if(s == "true" || s == "false") {
setColorReversal(s == "true");
}
}
auto letterSpaceRef = attrs.value("letterSpace");
if(!letterSpaceRef.isEmpty()) {
bool ok = false;
auto l = letterSpaceRef.toInt(&ok);
if(ok) {
QFont f = font();
f.setLetterSpacing(QFont::AbsoluteSpacing, l);
setFont(f);
}
}
auto fontFamilyRef = attrs.value("fontFamilay");
if(!fontFamilyRef.isEmpty()) {
setCustomFont(fontFamilyRef.toString());
}
setCustomAttrs(attrs);
}
void PicTextItem::saveAttrs(QXmlStreamAttributes &attrs)
{
attrs.append("dir", QString::number(direction()));
attrs.append("boldMultiple", QString::number(boldMultiple()));
attrs.append("colorReversal", colorReversal() ? "true" : "false");
attrs.append("letterSpace", QString::number(int(font().letterSpacing())));
attrs.append("fontFamilay", font().family());
saveCustomAttrs(attrs);
}
void PicTextItem::applyModify()
{
auto img = itemImage();
if(img.isNull()) {
img = emptyImage();
}
prepareGeometryChange();
m_itemImage = applyImgeTranslation(img);
update();
if(scene())
scene()->update();
}
QImage PicTextItem::preview()
{
return m_itemImage;
}
//! [1]
QVariant PicTextItem::itemChange(GraphicsItemChange change,
const QVariant &value)
{
if (change == ItemSceneChange && scene()) {
QPointF newPos = value.toPoint();
QRectF rect = scene()->sceneRect();
if (!rect.contains(newPos)) {
newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left())));
newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top())));
}
}
return QGraphicsItem::itemChange(change, value);
}
//! [1]
//! [2]
void PicTextItem::focusOutEvent(QFocusEvent *event)
{
// moveInput->hide();
emit lostFocus(this);
QGraphicsTextItem::focusOutEvent(event);
//
}
//! [2]
//! [5]
void PicTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
//if (textInteractionFlags() == Qt::NoTextInteraction)
// setTextInteractionFlags(Qt::TextEditorInteraction);
//setTextInteractionFlags(Qt::TextBrowserInteraction);
QGraphicsTextItem::mouseDoubleClickEvent(event);
//emit itemEdit(toHtml());
}
//! [5]
//限制图元拖动范围
void PicTextItem::mouseReleaseEvent ( QGraphicsSceneMouseEvent * event )
{
auto newPos = clampItemPos(pos());
this->setPos(qCeil(newPos.x()),qCeil(newPos.y()));
scene()->update();
QGraphicsTextItem::mouseReleaseEvent(event);
}
void PicTextItem::keyPressEvent(QKeyEvent *event)
{
foreach (QGraphicsItem *item, scene()->selectedItems()) {
QPointF newPos = item->pos();
switch(event->key()) {
case Qt::Key_Left:
newPos += QPointF(-1.0, 0.0);
break;
case Qt::Key_Right:
newPos += QPointF(1.0, 0.0);
break;
case Qt::Key_Up:
newPos += QPointF(0.0, -1.0);
break;
case Qt::Key_Down:
newPos += QPointF(0.0, 1.0);
break;
default:
break;
}
newPos = clampItemPos(newPos);
setPos(qCeil(newPos.x()),qCeil(newPos.y()));
}
if(!scene()->selectedItems().empty())
{
scene()->update();
}
QGraphicsTextItem::keyPressEvent(event);
}
QImage PicTextItem::emptyImage()
{
QImage img(10, 10, QImage::Format_ARGB32);
img.fill(Qt::white);
return img;
}
QImage PicTextItem::itemImage()
{
return m_untransImage;
}
void PicTextItem::setCustomAttrs(const QXmlStreamAttributes &attrs)
{
auto sourceVar = attrs.value("source").toString();
PicTextItem::setSource(sourceVar);
}
void PicTextItem::saveCustomAttrs(QXmlStreamAttributes &attrs)
{
attrs.append("source", PicTextItem::source().toString());
}
void PicTextItem::colorReversalChanged()
{
setSource(source());
}
void PicTextItem::letterSpaceChanged()
{
setSource(source());
}
QImage PicTextItem::strToImage(const QString &str)
{
QPainter painter;
QFontMetrics fm(font());
QImage img(fm.horizontalAdvance(str), fm.height(), QImage::Format_ARGB32);
QRgb txtColor = colorReversal() ? 0xffffffff : 0xff000000;
QRgb bgColor = colorReversal() ? 0xff000000 : 0x00000000;
img.fill(bgColor);
painter.begin(&img);
painter.setFont(font());
painter.setPen(txtColor);
painter.drawText(img.rect(), str);
painter.end();
return clipImage(img, bgColor);
}
/**
* @brief 限制item的位置,以保证整个item都在scene以内
* @param p 要设置的item的新位置
* @return 被clamp之后的新位置
*/
QPointF PicTextItem::clampItemPos(const QPointF &p)
{
return QPointF (std::min(qreal(scene()->width() - boundingRect().width()), std::max(0.0, p.x())),
std::min(qreal(scene()->height() - boundingRect().height()), std::max(0.0, p.y())));
}
+197
View File
@@ -0,0 +1,197 @@
#ifndef PICTEXTITEM_H
#define PICTEXTITEM_H
#include <QGraphicsTextItem>
#include <QPen>
#include <QGraphicsSceneMouseEvent>
#include <QImage>
#include <QXmlStreamAttributes>
#include <QHash>
class QFocusEvent;
class QGraphicsItem;
class QGraphicsScene;
class QGraphicsSceneMouseEvent;
enum ItemDirectionType {
NORMAL,
MIRROR_V,
MIRROR_H,
MIRROR_VH,
MIRROR_H_R270,
R90,
R270,
MIRROR_V_R270,
};
/**
* @brief 元素类型
* @remark
* 使用 @see PicTextItem::type() 获取元素类型
* 使用 @see PicTextItem::setSource 和 @see PicTextItem::source 读写item的来源
* 不同类型的元素,来源也不同
*/
enum SourceType{
UNKNOWN, // 未知, 目前未知类仅剩计数器类型
TEXT, // 文字类型,source: QString 文本字符串
IMAGE, // 图片类型, source: QString 图片位于本地的绝对路径
DATETIME, // 日期类型
SCHEDULE_SHIFT,
CODE, // 条形码和二维码
COUNTER,
};
class PicTextItem : public QGraphicsTextItem
{
Q_OBJECT
public:
enum { Type = UserType + 3 };
explicit PicTextItem(QGraphicsItem *parent = 0, QGraphicsScene *scene = 0, const SourceType type = SourceType::UNKNOWN);
virtual ~PicTextItem();
// 重写 QGraphicsTextItem 的 type 方法,用于 Qt graphics 系统标识区别于内置 Item 类型
int type() const
{ return Type; }
SourceType sourceType() const { return m_sourceType; }
virtual QVariant source();
virtual void setSource(QVariant var);
// 粗体,即水平拉伸倍率, 1倍率为保持原样
int boldMultiple() { return m_boldMultiple; }
int setBoldMultiple(int multiple);
// 图元方向
ItemDirectionType direction() { return m_direction; }
void setDirection(ItemDirectionType dir);
// 颜色翻转
bool colorReversal() { return m_colorReversal; }
void setColorReversal(bool b);
// 设置字体使用该方法而不是 QGraphicsItem::setFont
void setCustomFont(QString name);
// 文字列间距
int letterSpace();
void setLetterSpace(int space);
/**
* @brief 重写 QGraphicsTextItem 的 paint 方法,用于自定义绘制文字
*/
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
/**
* @brief 重写 QGraphicsTextItem 的 boundingRect 方法,用于自定义计算文字的边界矩形
*/
virtual QRectF boundingRect() const override;
/**
* @brief 重写 QGraphicsTextItem 的 shape 方法,用于自定义计算文字的路径
*/
QPainterPath shape() const override;
/**
* @brief setAttrs 将从xml工程文件中读取到的图元属性集应用到图元
* @param attrs
* @remark
* 该方法在 @see TestPrintWidget 从xml文件中载入场景文件时被调用,用于恢复图元状态
* setAttrs 从属性集中读取 direction, boldMultiple, colorReversal, letterSpace, fontSize 并应用这些属性
* setAttrs 在最后会调用 @see setCustomAttrs , 子类可以实现该方法继续读取自定义的属性
*/
void setAttrs(const QXmlStreamAttributes& attrs);
/**
* @brief saveAttrs @see setAttrs 的反向操作,用于将图元的属性集保存到xml文件,@see TestPrintWidget 在保存场景文件时会调用此方法
* @param attrs 图元将属性集保存到 attrs
*/
void saveAttrs(QXmlStreamAttributes& attrs);
/**
* @brief applyModify 应用 方向、水平拉伸、属性更改
*/
void applyModify();
/**
* @brief preview 获取图元当前的预览
* @return
*/
QImage preview();
signals:
void lostFocus(PicTextItem *item);
void selectedChange(QGraphicsItem *item);
void itemEdit(QString);
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
void focusOutEvent(QFocusEvent *event);
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent * event);
void keyPressEvent(QKeyEvent *event);
/**
* @brief emptyImage 返回一张10x10的空图片
* @return
* @remark 用于子类在 source 为空时返回一张空图片,避免渲染错误
*/
QImage emptyImage();
/**
* @brief itemImage 子类可以重新实现该方法用于返回已经渲染好了的但未应用方向、水平拉伸的图像
* @return
* @remark
* 对图元进行方向、水平拉伸的步骤由 @see applyImgeTranslation 实现,因此子类不需要
*/
virtual QImage itemImage();
virtual void setCustomAttrs(const QXmlStreamAttributes& attrs);
virtual void saveCustomAttrs(QXmlStreamAttributes& attrs);
/**
* @brief colorReversalChanged 颜色翻转通知, 子类重写该方法用于响应属性变更
*/
virtual void colorReversalChanged();
/**
* @brief letterSpaceChanged 字间距更改通知, 子类重写该方法用于响应属性变更
*/
virtual void letterSpaceChanged();
/**
* @brief strToImage 将字符串渲染至图片
* @param str 要转换的字符串
* @return 渲染文字后的图片已经被裁剪至最小 boudningRect
* @remark
* 方向将应用 PicTextItem 的字体和颜色翻转进行渲染
*/
QImage strToImage(const QString& str);
public slots:
private:
QPointF clampItemPos(const QPointF& p);
QImage applyImgeTranslation(QImage img);
public:
const SourceType m_sourceType;
QVariant m_source;
bool SpecialConditions;
int CatchCnt1StartValue;
int CatchCnt1CurrValue;
int m_boldMultiple = 1;
ItemDirectionType m_direction = NORMAL;
bool m_colorReversal = false;
QImage m_itemImage;
QImage m_untransImage;
};
#endif // PICTEXTITEM_H
+8
View File
@@ -0,0 +1,8 @@
#include "sceneviewwidget.h"
#include <QGraphicsScene>
SceneViewWidget::SceneViewWidget(QWidget *parent) :
QWidget(parent)
{
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef SCENEVIEWWIDGET_H
#define SCENEVIEWWIDGET_H
#include <QWidget>
#include <QGraphicsView>
class SceneViewWidget : public QWidget
{
Q_OBJECT
public:
explicit SceneViewWidget(QWidget *parent = 0);
QGraphicsView *pView;
signals:
public slots:
};
#endif // SCENEVIEWWIDGET_H