1042版本发行
This commit is contained in:
@@ -2756,6 +2756,8 @@ int DevOp::writeFpgaPrintPara(bool ignoreWarn){
|
||||
|
||||
|
||||
writeSyncAndDelayPrintCount(sysPara->para.enbSyncAndTimeTriggerLimit, sysPara->para.syncAndTimeTriggerLimit);
|
||||
LogInfo::setRunStatusText(QString("Sync and time trigger limit: %1, num: %2")
|
||||
.arg(sysPara->para.enbSyncAndTimeTriggerLimit).arg(sysPara->para.syncAndTimeTriggerLimit));
|
||||
|
||||
/*---------------------------------------------------------------------------------------*/
|
||||
setOscillatorVoltage(sysPara->para.oscillatorVoltage); //因为经过调整参数,所以开机也要多发送一次
|
||||
|
||||
+42
-11
@@ -801,7 +801,7 @@ void InkJetPrinter::timerHandler(void){
|
||||
if((QTime::currentTime()>=QTime(00,00,00))&&(QTime::currentTime()<=QTime(00,00,02))&&sysPara->para.Reciclar){
|
||||
if(m_MainWidget->getCurrPrintStatus() != 1){
|
||||
m_MainWidget->_on_pushButtonPowerOff_pressed(false);
|
||||
LogInfo::setRunStatusText(tr("测试时间结束,准备关机"));
|
||||
LogInfo::setRunStatusText(tr("定时开机循环完成,准备关机"));
|
||||
}
|
||||
}
|
||||
if(sysPara->status.selfCheckDone && sysPara->para.Reciclar && test_flag){
|
||||
@@ -871,6 +871,23 @@ void InkJetPrinter::timerHandler(void){
|
||||
if(sysPara->status.delay10s == 10){
|
||||
pulse_100s = 1;
|
||||
sysPara->status.delay10s = 0;
|
||||
|
||||
// if(sysPara->status.flagOfPowerOnMode && (ui->tabMainWindow->getCurrPrintStatus() != 1))
|
||||
if(sysPara->status.flagOfPowerOnMode)
|
||||
{
|
||||
qDebug()<<"waitPowerOffTime: "<<sysPara->status.waitPowerOffTime;
|
||||
LogInfo::setRunStatusText(tr("waitPowerOffTime: %1").arg(sysPara->status.waitPowerOffTime));
|
||||
if(sysPara->status.waitPowerOffTime)
|
||||
{
|
||||
sysPara->status.waitPowerOffTime--;
|
||||
if(!sysPara->status.waitPowerOffTime)
|
||||
{
|
||||
m_MainWidget->_on_pushButtonPowerOff_pressed(false);
|
||||
LogInfo::setRunStatusText(tr("定时开机循环完成,准备关机"));
|
||||
m_MainWidget->setRunStatus(tr("准备关机"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -956,9 +973,7 @@ void InkJetPrinter::timerHandler(void){
|
||||
// byons: 变量类图元现在优化为局部更新,避免每次都要把整个打印内容发送给FPGA,现在只发送被更新的列区间 2026年7月16日
|
||||
auto updateAreas = m_MainWidget->variableItemsUpdate();
|
||||
if(sysPara->status.isPrinting && !updateAreas.isEmpty()){
|
||||
for(const auto& area : updateAreas) {
|
||||
m_MainWidget->SendPrintDataToFpga(0, area.left(), area.width());
|
||||
}
|
||||
m_MainWidget->SendPrintDataToFpga(0, true);
|
||||
}
|
||||
|
||||
if (!updateAreas.isEmpty() && m_StackedWidget->currentWidget() == m_MainWidget) {
|
||||
@@ -1804,6 +1819,7 @@ void InkJetPrinter::saveFPGAStatus(unsigned char *data){
|
||||
if(sysPara->status.dummy != sysPara->status.isPrinting && sysPara->status.selfCheckDone){
|
||||
sysPara->status.isPrinting = sysPara->status.dummy;
|
||||
m_MainWidget->updatePrintDisplayLabel();
|
||||
emit printStatusChanged(sysPara->status.isPrinting);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1915,19 +1931,23 @@ void InkJetPrinter::savePulseCntVal(unsigned char *data){
|
||||
}
|
||||
}
|
||||
|
||||
void InkJetPrinter::saveSTM32Version(unsigned char *data){
|
||||
void InkJetPrinter::saveSTM32Version(unsigned char *data)
|
||||
{
|
||||
qDebug()<<"saveSTM32Version";
|
||||
static unsigned char STM32Verion[3] = {0}; //时间间隔内的脉冲累计数
|
||||
unsigned char *target= ((unsigned char *)&sysPara->status.stm32Verion);
|
||||
for(int i=0;i<data[3];i++){
|
||||
target[i]=data[4+i];
|
||||
}
|
||||
|
||||
QString STM32Ver = QString("%1.%2.%3").arg((sysPara->status.stm32Verion>>16)&0xFF)
|
||||
sysPara->status.flagOfPowerOnMode = (sysPara->status.stm32Verion>>23) & 0x01;
|
||||
if(sysPara->status.flagOfPowerOnMode)
|
||||
sysPara->status.waitPowerOffTime = 18;//半个小时
|
||||
else
|
||||
sysPara->status.waitPowerOffTime = 0;
|
||||
LogInfo::setRunStatusText(tr("flagOfPowerOnMode: %1").arg(sysPara->status.flagOfPowerOnMode));
|
||||
QString STM32Ver = QString("%1.%2.%3").arg((sysPara->status.stm32Verion>>16)&0x7F)
|
||||
.arg((sysPara->status.stm32Verion>>8) & 0xFF).arg(sysPara->status.stm32Verion&0xFF);
|
||||
qDebug()<<"STM32Ver:"<<STM32Ver;
|
||||
|
||||
LogInfo::setRunStatusText(QString("STM32Ver: %1").arg(STM32Ver));
|
||||
}
|
||||
|
||||
void InkJetPrinter::saveSTM32Time(unsigned char *data){
|
||||
@@ -2659,6 +2679,15 @@ bool InkJetPrinter::loadLastWorkAndPreparePrint()
|
||||
return loadWorkFileAndPreparePrint(lastFilename);
|
||||
}
|
||||
|
||||
void InkJetPrinter::restartPrintWhenSwitchedWorkFile(bool isPrinting)
|
||||
{
|
||||
if(!isPrinting) {
|
||||
m_MainWidget->on_m_StartBtn_clicked();
|
||||
auto ret = disconnect(this, &InkJetPrinter::printStatusChanged, this, &InkJetPrinter::restartPrintWhenSwitchedWorkFile);
|
||||
LogInfo::setRunStatusText(QString("Printing has restarted: %1").arg(ret));
|
||||
}
|
||||
}
|
||||
|
||||
bool InkJetPrinter::loadWorkFileAndPreparePrint(const QString &filename)
|
||||
{
|
||||
auto u8Filename = filename.toUtf8();
|
||||
@@ -2678,7 +2707,10 @@ bool InkJetPrinter::loadWorkFileAndPreparePrint(const QString &filename)
|
||||
|
||||
bool rePrint = false;
|
||||
if(sysPara->status.isPrinting && sysPara->status.selfCheckDone) {
|
||||
// connect(this, &InkJetPrinter::printStatusChanged,
|
||||
// this, &InkJetPrinter::restartPrintWhenSwitchedWorkFile, Qt::ConnectionType(Qt::DirectConnection | Qt::UniqueConnection));
|
||||
m_MainWidget->on_m_StopBtn_clicked();
|
||||
LogInfo::setRunStatusText("Pause printing first, then write to the new file");
|
||||
rePrint = true;
|
||||
}
|
||||
|
||||
@@ -2713,7 +2745,6 @@ bool InkJetPrinter::loadWorkFileAndPreparePrint(const QString &filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int highPressureCnt = 0;
|
||||
static unsigned int logCnt = 0;
|
||||
|
||||
@@ -3226,4 +3257,4 @@ void InkJetPrinter::onDlgFileOpen(const QString& filename)
|
||||
}
|
||||
|
||||
loadWorkFileAndPreparePrint(filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +156,8 @@ private:
|
||||
private slots:
|
||||
void onDlgFileOpen(const QString& filename);
|
||||
|
||||
void restartPrintWhenSwitchedWorkFile(bool isPrinting);
|
||||
|
||||
void slt_showMsg(QString msg);
|
||||
void timerHandler();
|
||||
void getMainWidgetButtonClickedSlot(int index);
|
||||
@@ -221,6 +223,8 @@ private slots:
|
||||
signals:
|
||||
void maintenanceShow();
|
||||
|
||||
void printStatusChanged(bool isPrinting);
|
||||
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* e) override;
|
||||
|
||||
@@ -202,7 +202,11 @@ void Logger::log(const QtMsgType type, const QString& message, const QString &fi
|
||||
mutex.lock();
|
||||
|
||||
LogMessage* logMessage=new LogMessage(type,message,logVars.localData(),file,function,line);
|
||||
|
||||
#ifndef BNS_DEBUG
|
||||
std::cout << qPrintable(logMessage->toString(msgFormat,"hh:mm:ss.zzz")) << std::flush;
|
||||
#endif
|
||||
|
||||
if (bufferSize>0)
|
||||
{
|
||||
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ void LogInfo::showVerionInformation(QString Mac,QString VernonBachVer, QString F
|
||||
if(!flag){
|
||||
QString machInfo;
|
||||
machInfo = "Mac:" + Mac + "\n";
|
||||
machInfo += "VernonBach Ver:" + VernonBachVer +"|"+STM32Ver+ "\n";
|
||||
machInfo += "QtUI Ver:" + VernonBachVer +"|"+STM32Ver+ "\n";
|
||||
machInfo += "FPGA Ver: NO" + FpgaVer + "\n";
|
||||
// machInfo += "PowerOnMode: " + QString::number(powerOnMode) + "\n";
|
||||
textEditMachInfo->append(machInfo);
|
||||
|
||||
@@ -78,6 +78,7 @@ linux-aarch64-gnu-g++ {
|
||||
bns-linux-aarch64-gnu-g++ {
|
||||
DEFINES += ARCH_AARCH64_GNU
|
||||
DEFINES += ARCH_AARCH64
|
||||
DEFINES += BNS_DEBUG
|
||||
}
|
||||
|
||||
HEADERS += Public.h \
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
#define VNLG
|
||||
SysPara::SysPara(void):
|
||||
devOp(new DevOp(this)){
|
||||
|
||||
|
||||
memset(¶,0,sizeof(para));
|
||||
memset(&status,0,sizeof(status));
|
||||
//qDebug("start to loadParaFromFile.");
|
||||
@@ -113,10 +111,6 @@ void SysPara::loadParaFromFile(){
|
||||
if(para.gearPumpSpeedAlarm < 1000 || para.gearPumpSpeedAlarm > 2000)
|
||||
para.gearPumpSpeedAlarm = 1500;
|
||||
|
||||
// 将flagOfReclaimPumEnable强制设置为0。该参数影响的是压力控制算法,但现在已经不使用 byons@2026年5月12日
|
||||
if(!para.flagOfReclaimPumEnable)
|
||||
para.flagOfReclaimPumEnable = true;
|
||||
|
||||
if (DeviceCodefile.isOpen()) {
|
||||
DeviceCodefile.close();
|
||||
}
|
||||
|
||||
@@ -1266,6 +1266,8 @@ typedef struct{
|
||||
unsigned int showInkWarningNumber;
|
||||
unsigned int showSolventWarningNumber;
|
||||
bool needMaintenanceRemind;
|
||||
bool flagOfPowerOnMode;
|
||||
unsigned int waitPowerOffTime;
|
||||
}sysStatus_t;
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
#define UP_PRINTER_MAJOR_VER 6
|
||||
#define UP_PRINTER_MINOR_VER 7
|
||||
#define UP_PRINTER_RIVISION_VER 4
|
||||
#define UP_PRINTER_RIVISION_VER 6
|
||||
#define SUB_VERSION "_KOR"
|
||||
#ifdef __RFID_OLD
|
||||
#define SUB_RFID "_RO"
|
||||
|
||||
+328
-330
File diff suppressed because it is too large
Load Diff
+190
-87
@@ -15,8 +15,8 @@
|
||||
3. [整体架构](#3-整体架构)
|
||||
4. [目录结构](#4-目录结构)
|
||||
5. [核心模块详解](#5-核心模块详解)
|
||||
6. [数据流与通信机制](#6-数据流与通信机制)
|
||||
7. [场景与打印渲染系统](#7-场景与打印渲染系统)
|
||||
6. [场景与打印渲染系统](#6-场景与打印渲染系统)
|
||||
7. [数据流与通信机制](#7-数据流与通信机制)
|
||||
8. [RFID刷卡模块](#8-rfid刷卡模块)
|
||||
9. [编译构建系统](#9-编译构建系统)
|
||||
10. [关键配置与宏定义](#10-关键配置与宏定义)
|
||||
@@ -65,25 +65,25 @@
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ UI 表现层 │
|
||||
│ InkJetPrinter (主窗口) + MainWidget (打印主界面) │
|
||||
│ 各功能页面: SystemManage, SystemSetting, LogInfo, ... │
|
||||
│ UI 表现层 │
|
||||
│ InkJetPrinter (主窗口) + MainWidget (打印主界面) │
|
||||
│ 各功能页面: SystemManage, SystemSetting, LogInfo, ... │
|
||||
│ 场景编辑器: TestPrintWidget, PicScene │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 业务逻辑层 │
|
||||
│ SysPara (系统参数管理) │
|
||||
│ SysPara (系统参数管理) │
|
||||
│ DevOp (设备操作) │
|
||||
│ RunTimeCtrl (运行时间统计) │
|
||||
│ RFIDManager (刷卡管理) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 通信层 │
|
||||
│ Serial (串口通信封装) │
|
||||
│ Modbus (Modbus协议) │
|
||||
│ Serial (串口通信封装) │
|
||||
│ Modbus (Modbus协议) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 硬件抽象层 │
|
||||
│ FPGA (喷印控制、充电电压、相位检测) │
|
||||
│ STM32 (墨路控制、传感器采集) │
|
||||
│ RFID读卡器 (IC卡读写) │
|
||||
│ STM32 (墨路控制、传感器采集) │
|
||||
│ RFID读卡器 (IC卡读写) │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -302,11 +302,7 @@ RunTimeCtrl (运行时间控制)
|
||||
- 计数器读写: 产品计数、同步计数
|
||||
|
||||
**FPGA地址空间**:
|
||||
通信地址与定义位于[连续墨点喷码机通信协议](连续墨点喷码机通信地址.xlsx),大致内存分布如下
|
||||
- `0x0000-0x01FF`: 状态读取区
|
||||
- `0xA400-0xA5FF`: 打印控制寄存器
|
||||
- `0xB000-0xCFFF`: 数据写入区(DAC表、打印数据、日历数据等)
|
||||
- `0xE000-0xFFFF`: 数字字符点阵数据
|
||||
通信地址与定义位于[连续墨点喷码机通信协议](连续墨点喷码机通信地址.xlsx)
|
||||
|
||||
### 5.6 串口通信 (Serial)
|
||||
|
||||
@@ -328,7 +324,14 @@ RunTimeCtrl (运行时间控制)
|
||||
|
||||
### 5.7 日志系统 (Log)
|
||||
|
||||
**职责**: 提供分级日志记录功能。
|
||||
#### 5.7.1 基于LogInfo的用户日志系统
|
||||
|
||||
**主要类**:
|
||||
- `LogInfo` - 用户日志的核心类,提供日志记录、显示和保存功能,跟踪用户操作和系统事件。
|
||||
|
||||
#### 5.7.2 基于QDebug的日志系统
|
||||
|
||||
**职责**: 提供程序运行时的日志记录功能,用于开发调试和问题排查。
|
||||
|
||||
**类层次**:
|
||||
- `Logger` - 日志基类,定义日志格式、级别过滤
|
||||
@@ -356,20 +359,164 @@ qCritical() << "error"; // 错误日志
|
||||
|
||||
---
|
||||
|
||||
## 6. 数据流与通信机制
|
||||
|
||||
### 6.1 打印数据流
|
||||
## 6. 场景与打印渲染系统
|
||||
|
||||
### 6.1 架构概述
|
||||
|
||||
场景系统基于 Qt Graphics View 框架,用于编辑和预览喷码内容。
|
||||
|
||||
```
|
||||
PicScene (QGraphicsScene) # 场景,管理所有图元
|
||||
├── 图元基类
|
||||
│ ├── PicTextItem # 普通文本
|
||||
│ ├── PicDateItem # 日期变量 (yyyy-MM-dd HH:mm:ss...)
|
||||
│ ├── PicCounterItem # 计数器 (可变数字)
|
||||
│ ├── PicImageItem # 图片 (Logo)
|
||||
│ ├── PicCodeItem # 条码/二维码
|
||||
│ └── PicScheduleShiftItem # 班次 (班次代码替换)
|
||||
│
|
||||
├── 图元编辑器
|
||||
│ ├── ItemEditor # 普通文本编辑器
|
||||
│ ├── DateVarSet # 日期变量编辑器
|
||||
│ ├── CounterCarSet # 计数器编辑器
|
||||
│ ├── ImageLoader # 图片读取器
|
||||
│ ├── BarcodeEditor # 条码/二维码编辑器
|
||||
│ └── ScheduleShiftsEditor # 班次 (班次代码替换)编辑器
|
||||
│
|
||||
├── 图元模型
|
||||
│ ├── ItemEditor # 普通文本编辑器
|
||||
│ ├── DateVarSet # 日期变量编辑器
|
||||
│ ├── CounterCarSet # 计数器编辑器
|
||||
│ ├── ImageLoader # 图片读取器
|
||||
│ ├── BarcodeEditor # 条码/二维码编辑器
|
||||
│ └── ScheduleShiftsEditor # 班次 (班次代码替换)编辑器
|
||||
|
||||
```
|
||||
|
||||
### 6.2 作业文件格式
|
||||
|
||||
作业文件使用XML格式(VBfiles结构),保存场景内容和打印设置:
|
||||
|
||||
```xml
|
||||
<VBfiles>
|
||||
<!-- 打印设置 -->
|
||||
<PrintSettings timeTriggerPrintMode="0" triggerInterval="90" ... />
|
||||
<!-- 文本图元 -->
|
||||
<VBfile>
|
||||
<pointer_x>55</pointer_x>
|
||||
<pointer_y>0</pointer_y>
|
||||
...
|
||||
<itemAttrs sourceType="1" dir="0" letterSpace="1" fontFamilay="WenQuanYi7" source="FGJ" ... />
|
||||
</VBfile>
|
||||
<!-- 日期图元 -->
|
||||
<VBfile>
|
||||
<pointer_x>55</pointer_x>
|
||||
<pointer_y>0</pointer_y>
|
||||
...
|
||||
<itemAttrs sourceType="3" datetimePattern="HH:mm:ss" ... />
|
||||
</VBfile>
|
||||
<!-- 计数器图元 -->
|
||||
<VBfile>
|
||||
<pointer_x>83</pointer_x>
|
||||
<pointer_y>17</pointer_y>
|
||||
...
|
||||
<itemAttrs sourceType="6" counter_type="7" digital_num="8" ... />
|
||||
</VBfile>
|
||||
<!-- 条码/二维码图元 -->
|
||||
<VBfile>
|
||||
<pointer_x>0</pointer_x>
|
||||
<pointer_y>0</pointer_y>
|
||||
...
|
||||
<itemAttrs sourceType="5" dir="0" barcodeContentPattern="dr66re{t}{c}" barcodeType="2" qrcodeFormat="0" ... />
|
||||
</VBfile>
|
||||
<!-- 图片图元 -->
|
||||
<VBfile>
|
||||
<pointer_x>0</pointer_x>
|
||||
<pointer_y>0</pointer_y>
|
||||
...
|
||||
<itemAttrs sourceType="2" dir="0" source="/home/plg/doc/scene.png" ... />
|
||||
</VBfile>
|
||||
</VBfiles>
|
||||
```
|
||||
|
||||
### 6.3 关键类说明
|
||||
|
||||
- **PicSceneLoader** - 场景文件的加载/保存/预览,负责XML序列化/反序列化
|
||||
- **ViewModels** - 定义 `DateItemModel`、`CounterViewModel` 等视图模型,用于编辑器与图元之间的数据传递
|
||||
- **ItemCommon** - 图元工具函数,如根据日期模型生成文本字符串
|
||||
- **打印设置** - `PrintSettingModel` 与作业文件绑定,包含触发模式、字宽、同步器参数等
|
||||
- **TestPrintWidget** - 场景编辑器,提供图元的创建、编辑、删除、预览功能
|
||||
|
||||
---
|
||||
|
||||
## 7. 数据流与通信机制
|
||||
|
||||
### 7.1 打印内容数据流
|
||||
|
||||
```
|
||||
用户编辑场景 (PicScene)
|
||||
└── 图元 (PicTextItem, PicDateItem, PicCodeItem, ...)
|
||||
└── 渲染为 QImage
|
||||
└── imageToPrintData() 转换为点阵数据
|
||||
└── SendPrintDataToFpga() 通过 Serial 发送
|
||||
└── FPGA 接收并驱动喷头喷印
|
||||
├── 普通静态图元 (PicTextItem, PicImageItem, ...)
|
||||
│ └─── onPreviewScene() 静态文本或图片渲染为 QImage
|
||||
│ └── imageToPrintData() 转换为点阵数据
|
||||
│ └── SendPrintDataToFpga() 在打印开始前一次性发送所有静态打印内容
|
||||
│ └── FPGA 接收并驱动喷头喷印
|
||||
│
|
||||
├─── PicCounterItem 计数器图元
|
||||
│ └── onPreviewScene() 构建变量控制结构体(位置、大小、类型等)
|
||||
│ └── DevOp::writeFpgaVariCtrl() 发送至FPGA,由FPGA直接硬件控制
|
||||
│
|
||||
└─── 软解动态图元 (PicDateItem PicScheduleShiftItem PicCodeItem)
|
||||
└── onPreviewScene() 与静态图元一样,进入onPreviewScene()
|
||||
└── variableItemsUpdate() 动态检查图元是否发生变化,更新数据
|
||||
└── SendPrintDataToFpga() 局部发送更新后的点阵数据至FPGA
|
||||
```
|
||||
|
||||
### 6.2 设备状态轮询
|
||||
**打印内容相关的几个重要的函数:**
|
||||
[SendPrintDataToFpga()](../mainwidget.cpp#L935) 负责将打印数据、打印设置和变量控制通过串口发送给FPGA,FPGA接收后驱动喷头进行喷印。该函数被设计成支持全量更新与局部更新,静态图元在打印开始前一次性发送,而动态图元则在每次变化时局部更新。局部更新时,SendPrintDataToFpga不会发送打印设置和变量控制数据,只会按列为单位更新打印缓冲区的点阵数据。
|
||||
|
||||
[imageToPrintData()](../mainwidget.cpp#L675) 将 QImage 转换为点阵数据,该函数可将图像填充至打印缓冲区的指定位置,随后由 SendPrintDataToFpga() 发送至FPGA。动态软解图元(如日期、计数器、二维码)在每次变化时调用该函数刷新打印缓冲区。
|
||||
|
||||
[onPreviewScene()](../mainwidget.cpp#L1888) 是场景预览的核心函数,负责将场景中的所有图元渲染为 QImage,并调用 imageToPrintData() 全量写入打印缓冲区。
|
||||
|
||||
[variableItemsUpdate()](../mainwidget.cpp#L1024) 动态检查图元是否发生变化,配合 imageToPrintData()、SendPrintDataToFpga() 实现局部更新打印数据。
|
||||
|
||||
|
||||
### 7.2 从文件到打印的数据流向
|
||||
本节中 *发送打印设置与打印内容到FPGA* 的术语基本可以代指调用[MainWidget::SendPrintDataToFpga](../mainwidget.cpp#L933)函数。
|
||||
|
||||
区别于标准VX5,此韩国定制版中,明确了发送打印内容与打印设置到FPGA的时机与作用范围,所有发送打印内容与打印设置的动作只在[MainWidget::on_m_StartBtn_clicked()](../mainwidget.cpp#L756)中进行,除此之外其它时机发送打印内容与设置的行为继承自标准VX5,实际在韩国定制版中属于冗余设计。
|
||||
|
||||
QtUI 按工作文件为单位对喷码内容进行管理,工作文件使用 XML 格式保存场景内容和打印设置。用户在编辑界面(TestPrintWidget)中创建或修改工作文件后,点击“保存”按钮将场景数据序列化为 XML 文件。随后,用户在打印主界面(MainWidget)中选择工作文件并点击“打印”。
|
||||
重要的工作流程位于[InkjetPrinter::loadWorkFileAndPreparePrint](../InkJetPrinter.cpp#L12684)函数中,流程如下:
|
||||
|
||||
```
|
||||
用户点击 [MainWidget::m_AddBtn](../MainWidget.cpp#L143) (调入文件喷印) 发送 sendButtonClickedSignal(2) 信号
|
||||
└── InkJetPrinter::getMainWidgetButtonClickedSlot() 接收信号打开 DialogFileOperation 对话框
|
||||
└── InkjetPrinter::loadWorkFileAndPreparePrint() 通过对话框输入的文件名打开文件
|
||||
└── PicSceneLoader::loadSceneFromFile() 解析 XML 文件,恢复场景内容和打印设置
|
||||
└── MainWidget::generatePrintContent() 将场景渲染为打印数据并写入缓冲区
|
||||
└── 等待用户按下 开始打印
|
||||
└── MainWidget::SendPrintDataToFpga() 全量发送打印数据与设置到FPGA,并开始打印
|
||||
```
|
||||
注意打开并解析工作文件的过程中不会直接发送打印数据到FPGA,只有在用户点击“打印”按钮后,才会调用 SendPrintDataToFpga() 将打印数据发送至FPGA。
|
||||
|
||||
### 7.3 工作文件编辑
|
||||
韩国QtUI中,*工作文件编辑* 被解耦为一个独立模块,它只负责对工作文件进行新建、编辑和调用[PicSceneLoader](../scene/PicSceneLoader.h)模块保存,其主要实现基本位于[TestPrintWidget](../testprintwidget.h),[TestPrintWidget](../testprintwidget.h)通过读取指定工作文件(或新建),在编辑完成后可以对文件进行保存。
|
||||
```
|
||||
用户点击 (新建文件) (编辑文件) 发送信号到InjkectPrinter
|
||||
└── InkJetPrinter判断当前文件名,将文件名传给TestPrintWidget,并切换到TestPrintWidget视图
|
||||
└── TestPrintWidget完成编辑后询问用户是否保存已编辑的工作文件
|
||||
├── 用户选择保存,TestPrintWidget 使用 PicSceneLoader 写入xml工作文件
|
||||
│ └─ 保存文件后发出信号通知 InjkectPrinter
|
||||
│ └─ InkjectPrinter 切换到 MainWidget 并调用 loadWorkFileAndPreparePrint 载入刚刚保存的文件
|
||||
│ └─ 之后的流程与 7.2 小节一致
|
||||
│
|
||||
└── 用户选择不保存,TestPrintWidget 直接发出信号通知 InjkectPrinter
|
||||
└─ InkjectPrinter 切换到 MainWidget,然后什么也不做
|
||||
```
|
||||
|
||||
### 7.4 设备状态轮询
|
||||
|
||||
```
|
||||
timerHandler()
|
||||
@@ -387,7 +534,7 @@ timerHandler()
|
||||
└── autoControlValvePump() # 自动控制执行
|
||||
```
|
||||
|
||||
### 6.3 信号槽通信概览
|
||||
### 7.5 信号槽通信概览
|
||||
|
||||
```
|
||||
Serial::receivedFromFPGA ──→ InkJetPrinter::saveFPGAStatus()
|
||||
@@ -398,56 +545,7 @@ RunTimeCtrl::sig_alertTimeout ──→ InkJetPrinter::slt_warningMaintenance()
|
||||
RFIDManager::sig_showMsg ──→ InkJetPrinter::slt_showMsg()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 场景与打印渲染系统
|
||||
|
||||
### 7.1 架构概述
|
||||
|
||||
场景系统基于 Qt Graphics View 框架,用于编辑和预览喷码内容。
|
||||
|
||||
```
|
||||
PicScene (QGraphicsScene) # 场景,管理所有图元
|
||||
└── myView (QGraphicsView) # 视图,提供缩放和交互
|
||||
└── 图元基类
|
||||
├── PicTextItem # 普通文本
|
||||
├── PicDateItem # 日期变量 (yyyy-MM-dd HH:mm:ss...)
|
||||
├── PicCounterItem # 计数器 (可变数字)
|
||||
├── PicImageItem # 图片 (Logo)
|
||||
├── PicCodeItem # 条码/二维码
|
||||
└── PicScheduleShiftItem # 班次 (班次代码替换)
|
||||
```
|
||||
|
||||
### 7.2 作业文件格式
|
||||
|
||||
作业文件使用XML格式(VBfiles结构),保存场景内容和打印设置:
|
||||
|
||||
```xml
|
||||
<VBfiles>
|
||||
<VBfile>
|
||||
<!-- 打印设置 -->
|
||||
<PrintSettings triggerMode="0" ... />
|
||||
<!-- 文本图元 -->
|
||||
<VB itemType="text" x="10" y="20" text="ABC" ... />
|
||||
<!-- 日期图元 -->
|
||||
<VB itemType="date" x="50" y="20" pattern="yyyy-MM-dd" ... />
|
||||
<!-- 计数器图元 -->
|
||||
<VB itemType="counter" x="100" y="20" counterType="7" ... />
|
||||
<!-- 条码/二维码图元 -->
|
||||
<VB itemType="code" x="10" y="50" codeType="QR" ... />
|
||||
<!-- 图片图元 -->
|
||||
<VB itemType="image" x="200" y="0" ... />
|
||||
</VBfile>
|
||||
</VBfiles>
|
||||
```
|
||||
|
||||
### 7.3 关键类说明
|
||||
|
||||
- **PicSceneLoader** - 场景文件的加载/保存/预览,负责XML序列化/反序列化
|
||||
- **ViewModels** - 定义 `DateItemModel`、`CounterViewModel` 等视图模型,用于编辑器与图元之间的数据传递
|
||||
- **ItemCommon** - 图元工具函数,如根据日期模型生成文本字符串
|
||||
- **ItemEditor** - 图元通用编辑器(字体、颜色、位置等)
|
||||
- **打印设置** - `PrintSettingModel` 与作业文件绑定,包含触发模式、字宽、同步器参数等
|
||||
|
||||
---
|
||||
|
||||
@@ -464,6 +562,7 @@ PicScene (QGraphicsScene) # 场景,管理所有图元
|
||||
- 保养卡识别与提醒
|
||||
- 自动扣减卡内余额
|
||||
- 卡片使用标记(防重复使用)
|
||||
- 超级卡的识别与处理
|
||||
|
||||
**加密**: 使用SM3(哈希)+ SM4(对称加密)国密算法保护卡片数据。
|
||||
|
||||
@@ -541,10 +640,12 @@ make
|
||||
```cpp
|
||||
#define UP_PRINTER_MAJOR_VER 6
|
||||
#define UP_PRINTER_MINOR_VER 7
|
||||
#define UP_PRINTER_RIVISION_VER 4
|
||||
#define UP_PRINTER_RIVISION_VER 5
|
||||
#define SUB_VERSION "_KOR"
|
||||
```
|
||||
|
||||
版本号分为年、月、本月第几次编译,SUB_VERSION表示是否是标准版,"_Std" 表示标准版,"_KOR" 表示韩国定制版、"_RFID" 表示是标准版基础上增加了刷卡功能,如果客户定制版本包含了刷卡功能,则显示客户后缀。
|
||||
|
||||
---
|
||||
|
||||
## 11. 上手指南
|
||||
@@ -552,15 +653,15 @@ make
|
||||
### 11.1 开发环境搭建
|
||||
|
||||
1. **安装Qt**: 推荐 Qt 5.12+ 用于桌面开发调试
|
||||
2. **获取代码**: 通过SVN或Git获取项目源码
|
||||
3. **编译运行**:
|
||||
```bash
|
||||
cd 项目目录
|
||||
qmake
|
||||
make
|
||||
./QtUI
|
||||
```
|
||||
4. **注意事项**: x86桌面版仅用于UI调试,硬件相关功能(串口、FPGA通信)不可用
|
||||
2. **获取代码**: 找到你的领导,通过SVN获取源码
|
||||
3. **编译运行**:
|
||||
1. 直接使用 InkjetUbuntu-T1 虚拟机中的 QtCreator 打开此项目,然后编译调试。
|
||||
2. 使用 VSCode ssh 连接 InkjetUbuntu-T2(从T1升级至Ubuntu20.04,以支持VSCode SSH连接) 虚拟机,然后直接在windows上远程开发,此方式需要自行配置编译环境,编译为ARM版本的命令为:
|
||||
```bash
|
||||
$ /home/inkjet/QtSDK/bin/qmake ./QtUI.pro -spec linux-aarch64-gnu-g++ CONFIG+=release
|
||||
$ make -j8
|
||||
```
|
||||
4. **注意事项**: x86桌面版仅用于UI调试,硬件相关功能(串口、FPGA通信)不可用。
|
||||
|
||||
### 11.2 代码阅读顺序建议
|
||||
|
||||
@@ -581,6 +682,7 @@ make
|
||||
| 修改FPGA通信 | `DevOp.h/cpp` + `Serial/` | 注意地址空间分配和CRC校验 |
|
||||
| 修改UI样式 | `.ui` 文件 | 使用 Qt Designer 编辑 |
|
||||
| 添加新功能页面 | 仿照现有页面模式 | 创建 .h/.cpp/.ui 三件套 |
|
||||
| 添加网络通信 ||
|
||||
|
||||
### 11.4 关键设计模式
|
||||
|
||||
@@ -591,9 +693,9 @@ make
|
||||
|
||||
### 11.5 调试技巧
|
||||
|
||||
1. **日志**: 使用 `qInfo()/qWarning()/qCritical()` 输出,日志文件位于 `/home/plg/conf/`
|
||||
1. **日志**: Debug模式下使用 `qInfo()/qWarning()/qCritical()` 输出,日志文件位于 `/home/plg/conf/`,发行版使用`LogInfo::setRunStatus()`
|
||||
2. **崩溃分析**: `dump.h/cpp` 安装了信号处理器,崩溃时会生成core dump
|
||||
3. **FPGA调试**: 可通过 `SystemManage` 界面手动控制阀门和泵
|
||||
3. **泵阀手动控制**: 可通过 `SystemManage` 界面手动控制阀门和泵
|
||||
4. **模拟模式**: 设置 `SIMULATE_PRINTING_MODE 1` 可在无硬件环境调试打印逻辑
|
||||
|
||||
### 11.6 注意事项
|
||||
@@ -611,5 +713,6 @@ make
|
||||
|
||||
**文档更新记录**
|
||||
|
||||
- 2026-07-23: 创建此文档 — 卜永仕
|
||||
- 2026-07-29:继续完善了此文档 - 卜永仕
|
||||
- 2026-07-23:创建此文档 — 卜永仕
|
||||
|
||||
|
||||
+328
-330
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,16 @@
|
||||
#include "loginfoctrl.h"
|
||||
|
||||
|
||||
LogInfoCtrl *LogInfoCtrl::instance()
|
||||
{
|
||||
static LogInfoCtrl* ins = nullptr;
|
||||
if (!ins) {
|
||||
ins = new LogInfoCtrl();
|
||||
}
|
||||
|
||||
return ins;
|
||||
}
|
||||
|
||||
void LogInfoCtrl::emitSigClean()
|
||||
{
|
||||
emit sig_clean();
|
||||
|
||||
+1
-4
@@ -8,10 +8,7 @@ class LogInfoCtrl : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static LogInfoCtrl* instance() {
|
||||
static LogInfoCtrl ins;
|
||||
return &ins;
|
||||
}
|
||||
static LogInfoCtrl* instance();
|
||||
|
||||
void emitSigClean();
|
||||
void emitSigCleanOver(bool flag);
|
||||
|
||||
+239
-566
@@ -31,6 +31,7 @@
|
||||
#include "scene/PicDateItem.h"
|
||||
#include "scene/PicScheduleShiftItem.h"
|
||||
#include "scene/piccodeitem.h"
|
||||
#include "scene/PicCounterItem.h"
|
||||
#include <QElapsedTimer>
|
||||
#include <QScroller>
|
||||
|
||||
@@ -530,6 +531,8 @@ QList<QRect> MainWidget::variableItemsUpdate()
|
||||
return QList<QRect>();
|
||||
}
|
||||
|
||||
/*
|
||||
旧实现:
|
||||
int totalOfProcessedDots = 0;
|
||||
int totalOfDatetimeNumber = 0;
|
||||
int nbInvaliedDatetimePreview = 0;
|
||||
@@ -537,6 +540,38 @@ QList<QRect> MainWidget::variableItemsUpdate()
|
||||
|
||||
QList<QRect> updateAreas;
|
||||
|
||||
auto items = pPicScene->items();
|
||||
for(auto i : items) {
|
||||
PicTextItem* item = dynamic_cast<PicTextItem*>(i);
|
||||
if(!item)
|
||||
continue;
|
||||
|
||||
...
|
||||
|
||||
auto boundingRect = pPicScene->itemsBoundingRect().toRect();
|
||||
QRect itemRect(item->pos().x() - boundingRect.x(), item->pos().y() - boundingRect.y(), img.width(), img.height());
|
||||
...
|
||||
|
||||
QRect intersectRect = itemRect.intersected(sceneRect);
|
||||
...
|
||||
}
|
||||
*/
|
||||
|
||||
int totalOfProcessedDots = 0;
|
||||
int totalOfDatetimeNumber = 0;
|
||||
int nbInvaliedDatetimePreview = 0;
|
||||
int nbClipDatetimePreview = 0;
|
||||
|
||||
QList<QRect> updateAreas;
|
||||
|
||||
const QRectF contentRect = pPicScene->itemsBoundingRect();
|
||||
if(contentRect.isEmpty())
|
||||
return updateAreas;
|
||||
|
||||
const int maxPicWidth = sysPara->status.flagOfNo67FPGA ? MAX_PRINT_COL_NUM_Normal : MAX_PRINT_COL_NUM_Wide;
|
||||
const int maxPicHeight = MAX_PRINT_ROW_NUM;
|
||||
const QRectF outputRect(0, 0, maxPicWidth, maxPicHeight);
|
||||
|
||||
auto items = pPicScene->items();
|
||||
for(auto i : items) {
|
||||
PicTextItem* item = dynamic_cast<PicTextItem*>(i);
|
||||
@@ -570,8 +605,8 @@ QList<QRect> MainWidget::variableItemsUpdate()
|
||||
auto codeItem = dynamic_cast<PicCodeItem*>(item);
|
||||
if(!codeItem)
|
||||
continue;
|
||||
|
||||
QVector<int> counterValus{QString::number(sysPara->status.calandar_and_dat.cnt1CurrValue,16).toInt(),
|
||||
|
||||
QVector<int> counterValus{QString::number(sysPara->status.calandar_and_dat.cnt1CurrValue,16).toInt(),
|
||||
QString::number(sysPara->status.calandar_and_dat.cnt2CurrValue,16).toInt()};
|
||||
auto b = codeItem->updateVariants(counterValus);
|
||||
if(!b)
|
||||
@@ -584,34 +619,24 @@ QList<QRect> MainWidget::variableItemsUpdate()
|
||||
continue;
|
||||
}
|
||||
|
||||
auto sceneRect = pPicScene->sceneRect().toRect();
|
||||
auto boundingRect = pPicScene->itemsBoundingRect().toRect();
|
||||
QRect itemRect(item->pos().x() - boundingRect.x(), item->pos().y() - boundingRect.y(), img.width(), img.height());
|
||||
totalOfDatetimeNumber++;
|
||||
|
||||
// 裁剪item位置, 确保item位于场景内
|
||||
// 如果item超出了场景范围,则裁剪img并更新itemRect,只显示场景内的部分
|
||||
QRect intersectRect = itemRect.intersected(sceneRect);
|
||||
|
||||
if(!intersectRect.isEmpty() && intersectRect != itemRect) {
|
||||
// 计算裁剪区域在原图中的偏移
|
||||
int cropX = qMax(0, (int)(intersectRect.left() - itemRect.left()));
|
||||
int cropY = qMax(0, (int)(intersectRect.top() - itemRect.top()));
|
||||
int cropWidth = (int)intersectRect.width();
|
||||
int cropHeight = (int)intersectRect.height();
|
||||
|
||||
// 裁剪图像
|
||||
img = img.copy(cropX, cropY, cropWidth, cropHeight);
|
||||
|
||||
// 更新itemRect为裁剪后的区域
|
||||
itemRect = intersectRect;
|
||||
const QRectF itemSceneRect = item->sceneBoundingRect();
|
||||
const QRectF itemBufferRect = itemSceneRect.translated(-contentRect.topLeft());
|
||||
const QRectF clippedBufferRect = itemBufferRect.intersected(outputRect);
|
||||
if(clippedBufferRect.isEmpty())
|
||||
continue;
|
||||
|
||||
QRect targetRect = clippedBufferRect.toAlignedRect();
|
||||
totalOfDatetimeNumber++;
|
||||
|
||||
if(targetRect != itemBufferRect.toAlignedRect()) {
|
||||
const int cropX = qMax(0, targetRect.left() - itemBufferRect.toAlignedRect().left());
|
||||
const int cropY = qMax(0, targetRect.top() - itemBufferRect.toAlignedRect().top());
|
||||
img = img.copy(cropX, cropY, targetRect.width(), targetRect.height());
|
||||
++nbClipDatetimePreview;
|
||||
}
|
||||
|
||||
totalOfProcessedDots += imageToPrintData(img, (int)itemRect.left(), (int)itemRect.top());
|
||||
|
||||
updateAreas.append(itemRect);
|
||||
totalOfProcessedDots += imageToPrintData(img, targetRect.left(), targetRect.top());
|
||||
updateAreas.append(targetRect);
|
||||
}
|
||||
|
||||
if(updateAreas.isEmpty())
|
||||
@@ -667,12 +692,15 @@ int MainWidget::imageToPrintData(QImage &image, int startX, int startY)
|
||||
for(int k = 0; k < height; k++)
|
||||
{
|
||||
QRgb rgb = image.pixel(j, k);
|
||||
if(((rgb >> 24) & 0xff) > 0x80)
|
||||
{
|
||||
c |= (1 << (hStart % 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rgb & 0x80000000) { // 判断 alpha
|
||||
// 灰度计算:Y = 0.299*R + 0.587*G + 0.114*B
|
||||
int y = int((((rgb & 0xff) * 299 + ((rgb >> 8) & 0xff) * 587 + ((rgb >> 16) & 0xff) * 114)) / 1000.0f);
|
||||
if (y < 125) {
|
||||
c |= (1 << (hStart % 8));
|
||||
} else {
|
||||
c &= ~(1 << (hStart % 8));
|
||||
}
|
||||
} else {
|
||||
c &= ~(1 << (hStart % 8));
|
||||
}
|
||||
|
||||
@@ -795,6 +823,7 @@ void MainWidget::on_m_StartBtn_clicked()
|
||||
sysPara->saveParaToFile();
|
||||
}
|
||||
|
||||
// onPreviewScene 没有必要再次调用,评估后删除 byons@2026年7月28日
|
||||
if(sysPara->para.EditMode == SCENE)
|
||||
onPreviewScene();
|
||||
|
||||
@@ -899,19 +928,16 @@ void MainWidget::on_m_StopBtn_clicked()
|
||||
}
|
||||
|
||||
unsigned char blankDat1[BLANK_COL_NUM*MAX_PRINT_ROW_BYTE_NUM]={0};
|
||||
void MainWidget::SendPrintDataToFpga(unsigned char alterMode, int startCol, int size)
|
||||
void MainWidget::SendPrintDataToFpga(unsigned char alterEnable, bool isUpdate)
|
||||
{
|
||||
if(!sysPara) return ;
|
||||
// fileChange=false;
|
||||
|
||||
Q_UNUSED(alterMode);
|
||||
Q_UNUSED(alterEnable);
|
||||
|
||||
// 看清楚,最后取反,也就是说,如果不是局部更新,则写入打印设置和变量控制
|
||||
if(!(startCol >= 0 && size > 0)) {
|
||||
if(!isUpdate) {
|
||||
sysPara->devOp->writeFpgaPrintPara(1);
|
||||
sysPara->devOp->writeFpgaVariCtrl();
|
||||
startCol = 0;
|
||||
size = sysPara->status.currPrintCol;
|
||||
}
|
||||
|
||||
sysPara->devOp->fpgaWr(0,blankDat1,sizeof(blankDat1));//...所加的空白偏移地址
|
||||
@@ -930,14 +956,11 @@ void MainWidget::SendPrintDataToFpga(unsigned char alterMode, int startCol, int
|
||||
dat =sysPara->status.printDat;
|
||||
sizeofdat = sizeof(sysPara->status.printDat);
|
||||
}
|
||||
if(sysPara->status.currPrintCol* MAX_PRINT_ROW_BYTE_NUM <= 20000)
|
||||
sysPara->devOp->fpgaWr(sizeof(blankDat1),dat, sysPara->status.currPrintCol* MAX_PRINT_ROW_BYTE_NUM);
|
||||
else
|
||||
sysPara->devOp->fpgaWrD2(sizeof(blankDat1),dat, sysPara->status.currPrintCol* MAX_PRINT_ROW_BYTE_NUM);
|
||||
|
||||
dat = dat + startCol * MAX_PRINT_ROW_BYTE_NUM;
|
||||
size = size * MAX_PRINT_ROW_BYTE_NUM;
|
||||
|
||||
if(size <= 20000)
|
||||
sysPara->devOp->fpgaWr(sizeof(blankDat1), dat, size);
|
||||
else
|
||||
sysPara->devOp->fpgaWrD2(sizeof(blankDat1), dat, size);
|
||||
|
||||
static QElapsedTimer bnsTimer;
|
||||
static uint64_t nbRestartCount = 0;
|
||||
@@ -1822,8 +1845,30 @@ int MainWidget::getMaxSpeedCalcPara(){
|
||||
return pulseNum;
|
||||
}
|
||||
|
||||
|
||||
QRect clipBottom(const QImage& img, const QRect& region)
|
||||
{
|
||||
for(int y = region.bottom() - 1; y >= region.top(); --y) {
|
||||
auto line = img.scanLine(y);
|
||||
for(int x = region.left(); x < region.right(); ++x) {
|
||||
auto rgb = *((const uint32_t*)(x * 4 + line));
|
||||
int y = int((((rgb & 0xff) * 299 + ((rgb >> 8) & 0xff) * 587 + ((rgb >> 16) & 0xff) * 114)) / 1000.0f);
|
||||
if((rgb & 0x80000000) && y < 125) {
|
||||
return QRect(QPoint(region.topLeft()), QPoint(region.right(), y + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QRect(region.topLeft(), QSize(region.width(), 0));
|
||||
}
|
||||
|
||||
void MainWidget::onPreviewScene()
|
||||
{
|
||||
if(!sysPara){
|
||||
qCritical() << "SysPara is empty!";
|
||||
return;
|
||||
}
|
||||
|
||||
sysPara->para.EditMode = SCENE;
|
||||
|
||||
if(!pPicScene) {
|
||||
@@ -1831,547 +1876,176 @@ void MainWidget::onPreviewScene()
|
||||
}
|
||||
|
||||
pPicScene->clearSelection();
|
||||
pPicScene->update();
|
||||
|
||||
QRect sceneRect = pPicScene->itemsBoundingRect().toRect();
|
||||
QSize size = sceneRect.size();
|
||||
bool MaxCol4000;
|
||||
if(sysPara->status.flagOfNo67FPGA)
|
||||
MaxCol4000 = true;
|
||||
else
|
||||
MaxCol4000 = false;
|
||||
|
||||
unsigned char *dat;
|
||||
if(MaxCol4000){
|
||||
dat = sysPara->status.printDat_Normal;
|
||||
memset(dat,0,sizeof(sysPara->status.printDat_Normal));
|
||||
}else{
|
||||
dat = sysPara->status.printDat;
|
||||
memset(dat,0,sizeof(sysPara->status.printDat));
|
||||
}
|
||||
|
||||
const QRectF contentRect = pPicScene->itemsBoundingRect();
|
||||
const QRect sceneRect = contentRect.toAlignedRect();
|
||||
qDebug() << "sceneRect: " << sceneRect;
|
||||
|
||||
// 限定最大高度和宽度
|
||||
int coldot = qMin(sceneRect.width(), MaxCol4000 ? MAX_PRINT_COL_NUM_Normal : MAX_PRINT_COL_NUM_Wide);
|
||||
int maxPicHeight = qMin(sceneRect.height(), int(sysPara->para.canvasHeight));
|
||||
QSize size(coldot,maxPicHeight);
|
||||
|
||||
if(size.isEmpty()) {
|
||||
//场景为空时,渲染空场景并刷新界面
|
||||
handleEmptySize();
|
||||
return;
|
||||
}
|
||||
QImage image(size,QImage::Format_ARGB32);
|
||||
|
||||
QImage image(size, QImage::Format_ARGB32);
|
||||
image.fill(0x00ffffff);//填充白色
|
||||
//image.save("./printScene.jpg");//图片
|
||||
|
||||
QPainter painter(&image);
|
||||
pPicScene->render(&painter,QRectF(), sceneRect);
|
||||
|
||||
int coldot=0;
|
||||
if(sysPara){
|
||||
bool MaxCol4000;
|
||||
if(sysPara->status.flagOfNo67FPGA)
|
||||
MaxCol4000 = true;
|
||||
else
|
||||
MaxCol4000 = false;
|
||||
previewFlag=1;
|
||||
sysPara->status.currPrintRow = 0;
|
||||
sysPara->status.variNum = 0;
|
||||
sysPara->status.QRvariNum = 0;
|
||||
unsigned char *dat;
|
||||
if(MaxCol4000){
|
||||
dat =sysPara->status.printDat_Normal;
|
||||
memset(dat,0,sizeof(sysPara->status.printDat_Normal));
|
||||
}else{
|
||||
dat =sysPara->status.printDat;
|
||||
memset(dat,0,sizeof(sysPara->status.printDat));
|
||||
}
|
||||
//qDebug()<<"Preview:";
|
||||
int firstRow = 0;
|
||||
|
||||
{
|
||||
sysPara->status.addSpace = sysPara->para.checkSpace;
|
||||
int myvariNum=0;
|
||||
int expiryVarNum = 0;
|
||||
|
||||
coldot = sceneRect.width();
|
||||
if(coldot > (MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide))
|
||||
coldot = MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide;
|
||||
int maxPicHeight = MAX_PRINT_ROW_NUM + 12;
|
||||
QSize size(coldot,maxPicHeight);
|
||||
sysPara->status.variNum = 0;
|
||||
sysPara->status.QRvariNum = 0;
|
||||
sysPara->status.addSpace = sysPara->para.checkSpace; // 空列已经弃用 __attribute__((deprecated))
|
||||
sysPara->status.currPrintRow = 0;
|
||||
sysPara->status.currPrintCol = coldot;
|
||||
sysPara->status.ExpiryVarNum = 0;
|
||||
sysPara->print.ExpiryVar.startColPos = 0;
|
||||
sysPara->print.ExpiryVar.endRowPos = 0;
|
||||
sysPara->print.ExpiryVar.letterSpace =0;
|
||||
sysPara->print.CurDateVar.startColPos = 0;
|
||||
sysPara->print.CurDateVar.endRowPos = 0;
|
||||
sysPara->print.CurDateVar.letterSpace = 0;
|
||||
sysPara->status.CurrDateVariNum = 0;
|
||||
|
||||
sysPara->status.currPrintRow =0;
|
||||
sysPara->status.currPrintCol = coldot + ( sysPara->status.addSpace?coldot:0) ; //checkSpace
|
||||
qDebug() << "Loading scene items: \r\n\r\n\r\n";
|
||||
|
||||
QImage image(size,QImage::Format_ARGB32);
|
||||
image.fill(0x00ffffff);//填充白色
|
||||
QPainter painter(&image);
|
||||
QRectF validRectF(sceneRect.x(),sceneRect.y(),coldot,maxPicHeight);
|
||||
pPicScene->render(&painter,QRectF(),validRectF);
|
||||
int firstRow = 0;
|
||||
int lastRow = firstRow + MAX_PRINT_ROW_NUM;
|
||||
int TempVarNum=0;
|
||||
int varLastRow=0;
|
||||
lastRow = (lastRow>maxPicHeight)?maxPicHeight:lastRow;
|
||||
QList<QGraphicsItem *> items = pPicScene->items();
|
||||
foreach (QGraphicsItem *item, items) {
|
||||
|
||||
// 接下来就是要把打印到数据data填充以及确认变量的个数,变量对应的开始列和结束行
|
||||
for(int j = 0; j < lastRow - firstRow; j++){ // Y
|
||||
for(int i = 0; i < coldot; i++){ //
|
||||
QRgb rgb = image.pixel(i,j + firstRow);
|
||||
if(rgb&0x80000000){ //判断alpha
|
||||
if((rgb & 0xf0f0ff) == 0xf0f000){ //处理变量, 查找左下角,因为同一行的左下角是对齐的 看起来这个颜色是黄色
|
||||
|
||||
bool foundvar=0;
|
||||
if(j>0){
|
||||
QRgb r_rgb = image.pixel(i,j + firstRow+1);
|
||||
if((r_rgb & 0xf0f0ff) != 0xf0f000 ){foundvar =1;}
|
||||
//QRgb r_rgb = image.pixel(i,j + firstRow-1);if((r_rgb & 0xf0f0ff) == 0xf0f000 )foundvar =0;
|
||||
}
|
||||
if(foundvar){
|
||||
if(sysPara->status.variNum < MAX_VARI_NUM){
|
||||
sysPara->status.vars[sysPara->status.variNum].startColPos = i+(sysPara->status.addSpace?i:0);
|
||||
sysPara->status.vars[sysPara->status.variNum].endRowPos = j;
|
||||
//if(varLastRow<j+1) varLastRow=j+1;
|
||||
//sysPara->status.variNum ++;TempVarNum++;
|
||||
//i+=5;//scene 每一行可能都包含变量
|
||||
//qDebug()<<"VARr:"<<TempVarNum<<i<<j;
|
||||
}
|
||||
else TempVarNum++;
|
||||
//dat[MAX_PRINT_ROW_BYTE_NUM*i + j/8] |= 1 << (j%8); //画黑点
|
||||
}
|
||||
}
|
||||
|
||||
else if( ((rgb & 0xfffff0) == 0x00ff10) || ((rgb & 0xfffff0) == 0x00ff20) ||((rgb & 0xfffff0) == 0x00ff30) ){
|
||||
// 0xff00ff01(DMT) 0xff00ff02(QR) 0xff00ff03(BAR)
|
||||
//qDebug()<<"FLAG:"<<i<<j+1<<QString().sprintf("%08X", rgb);
|
||||
if(sysPara->status.QRvariNum>=4)continue;
|
||||
if((rgb & 0x00ffff0) == 0x00ff10) { //MDT
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].type=MDT;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].countEn=1;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].Counter=sysPara->status.productCnt;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].startColPos=i+(sysPara->status.addSpace?i:0);
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].endRowPos=j+1;
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
sysPara->status.QRvariNum++;
|
||||
}
|
||||
else if((rgb & 0x00ffff0) == 0x00ff20) { //QR
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].type=QR;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].countEn=1;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].Counter=sysPara->status.productCnt;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].startColPos=i+(sysPara->status.addSpace?i:0);
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].endRowPos=j+1;
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
sysPara->status.QRvariNum++;
|
||||
}
|
||||
else if((rgb & 0x00fffff0) == 0x00ff30) { //BAR
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].type=BAR;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].countEn=1;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].Counter=sysPara->status.productCnt;
|
||||
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].startColPos=i+(sysPara->status.addSpace?i:0);
|
||||
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].endRowPos=j+1;
|
||||
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
sysPara->status.QRvariNum++;
|
||||
|
||||
}
|
||||
if(sysPara->status.QRvariNum>=4)sysPara->status.QRvariNum=4;
|
||||
|
||||
}
|
||||
else if((rgb & 0x00ffffff)==EXPIRY_VARI_RECONISE)
|
||||
{ // 有效期变量 : 处理变量, 查找左下角,因为同一行的左下角是对齐的
|
||||
bool foundExVar=0;
|
||||
if(j>0){
|
||||
QRgb r_rgb = image.pixel(i,j + firstRow+1);
|
||||
if((r_rgb & 0x00ffffff) != EXPIRY_VARI_RECONISE ){foundExVar =1;}
|
||||
}
|
||||
if(foundExVar)
|
||||
{
|
||||
if(sysPara->status.ExpiryVarNum <2)
|
||||
{
|
||||
sysPara->print.ExpiryVar.startColPos = i+(sysPara->status.addSpace?i:0);
|
||||
sysPara->print.ExpiryVar.endRowPos = j;
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
sysPara->status.ExpiryVarNum ++;
|
||||
i+=5;
|
||||
}
|
||||
//else TempVarNum++;
|
||||
//dat[MAX_PRINT_ROW_BYTE_NUM*i + j/8] |= 1 << (j%8); //画黑点
|
||||
}
|
||||
}
|
||||
else if((rgb & 0xfffff0)==0xff0cf0)
|
||||
{ // 有效期变量 : 处理变量, 查找左下角,因为同一行的左下角是对齐的
|
||||
bool foundExVar=0;
|
||||
if(j>0){
|
||||
QRgb r_rgb = image.pixel(i,j + firstRow+1);
|
||||
if((r_rgb & 0xfffff0) != 0xff0cf0 ){foundExVar =1;}
|
||||
}
|
||||
if(foundExVar)
|
||||
{
|
||||
if(sysPara->status.ExpiryVarNum <2)
|
||||
{
|
||||
sysPara->print.CurDateVar.startColPos = i+(sysPara->status.addSpace?i:0);
|
||||
sysPara->print.CurDateVar.endRowPos = j;
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
sysPara->status.CurrDateVariNum ++;
|
||||
i+=5;
|
||||
}
|
||||
//else TempVarNum++;
|
||||
//dat[MAX_PRINT_ROW_BYTE_NUM*i + j/8] |= 1 << (j%8); //画黑点
|
||||
}
|
||||
}
|
||||
else if((rgb & 0xffffff)==0xff00ff)
|
||||
{ // 有效期变量 : 处理变量, 查找左下角,因为同一行的左下角是对齐的
|
||||
{
|
||||
if(sysPara->status.classVariNum <3) {
|
||||
EXPIRYVAR_t *currCLass = &sysPara->print.ClassVari ;
|
||||
currCLass->day = QDateTime::currentDateTime().date().day();
|
||||
currCLass->startColPos = i+(sysPara->status.addSpace?i:0);
|
||||
currCLass->endRowPos = j;
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
sysPara->status.classVariNum ++;
|
||||
i+=5;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //Y = 0.299*R' + 0.587*G' + 0.114*B //非变量
|
||||
int y = (((rgb&0xff)*299 + ((rgb>>8)&0xff)*587 + ((rgb>>16)&0xff)*114))/1000;
|
||||
if(y < 125 ){
|
||||
dat[MAX_PRINT_ROW_BYTE_NUM*(i+(sysPara->status.addSpace?i:0)) + j/8] |= 1 << (j%8); //画黑点
|
||||
if((j+1) > sysPara->status.currPrintRow) {
|
||||
sysPara->status.currPrintRow = j+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}/*判断alpha end*/
|
||||
}
|
||||
}
|
||||
|
||||
if(TempVarNum>MAX_VARI_NUM){
|
||||
setRunStatus(tr("变量数大于8个,某些变量将不起作用!!!"));
|
||||
strTitle= tr("变量数大于8个,某些变量将不起作用!!!");
|
||||
strTitle.append("\r\n");
|
||||
strTitle.append(tr("请减少信息中的变量(或计数器)数量."));
|
||||
QMessageBox::warning(this, tr("警告"),strTitle,QMessageBox::Ok);
|
||||
}
|
||||
|
||||
sysPara->status.variNum = 0;
|
||||
sysPara->status.ExpiryVarNum = 0;
|
||||
sysPara->print.ExpiryVar.startColPos = 0;
|
||||
sysPara->print.ExpiryVar.endRowPos = 0;
|
||||
sysPara->print.ExpiryVar.letterSpace =0;
|
||||
sysPara->print.CurDateVar.startColPos = 0;
|
||||
sysPara->print.CurDateVar.endRowPos = 0;
|
||||
sysPara->print.CurDateVar.letterSpace = 0;
|
||||
sysPara->status.CurrDateVariNum = 0;
|
||||
sysPara->status.QRvariNum=0;//lch add
|
||||
int myvariNum=0;
|
||||
int expiryVarNum = 0;
|
||||
|
||||
QList<QGraphicsItem *> items = pPicScene->items();
|
||||
foreach (QGraphicsItem *item, items) {
|
||||
PicTextItem *picText = qgraphicsitem_cast<PicTextItem*>(item);
|
||||
bool ok;
|
||||
int textvariNum=0;
|
||||
|
||||
int textColdot=0;
|
||||
textColdot = picText->boundingRect().width();
|
||||
if(textColdot > (MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide))
|
||||
textColdot = MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide;
|
||||
int maxTextHeight = MAX_PRINT_ROW_NUM + 12;
|
||||
QSize textSize(textColdot, maxTextHeight);
|
||||
QImage textImage(textSize,QImage::Format_ARGB32);
|
||||
textImage.fill(0x00ffffff);//填充白色
|
||||
//image.fill(0x00f0f000);//填充白色
|
||||
QPainter textPainter(&textImage);
|
||||
//textImage.save("./textImage.jpg");
|
||||
|
||||
//QRectF validtextRectF(picText->pos().x(),picText->pos().y(),textColdot,maxTextHeight);
|
||||
QRectF validtextRectF(picText->pos().x(),picText->pos().y(),textColdot,picText->document()->size().height());
|
||||
pPicScene->render(&textPainter,QRectF(),validtextRectF);
|
||||
//qDebug()<<"validtextRectF:"<<validtextRectF;
|
||||
//textImage.save("./textImage.bmp");
|
||||
int textFirstRow = 0;
|
||||
//qDebug()<<"textFirstRow:"<<textFirstRow;
|
||||
int textLastRow = textFirstRow + MAX_PRINT_ROW_NUM;
|
||||
int textItemPosX;
|
||||
int textItemPosY;
|
||||
textItemPosX = picText->pos().x() - sceneRect.x();
|
||||
textItemPosY = picText->pos().y() - sceneRect.y();
|
||||
|
||||
//接下来就是要把打印到数据data填充以及确认变量的个数,变量对应的开始列和结束行
|
||||
for(int j = 0; j < textLastRow - textFirstRow; j++){ // Y
|
||||
for(int i = 0; i < textColdot; i++){ //
|
||||
QRgb rgb = textImage.pixel(i,j + textFirstRow);
|
||||
if((rgb&0x80000000)){ //判断alpha
|
||||
if((rgb & 0xf0f0ff) == 0xf0f000){ //处理变量, 查找左下角,因为同一行的左下角是对齐的 看起来这个颜色是黄色
|
||||
|
||||
bool textfoundvar = 0;
|
||||
if(j>0){
|
||||
QRgb r_rgb = textImage.pixel(i,j + textFirstRow+1);
|
||||
if((r_rgb & 0xf0f0ff) != 0xf0f000 )
|
||||
{
|
||||
textfoundvar =1;
|
||||
}
|
||||
|
||||
}
|
||||
if(textfoundvar){
|
||||
if(sysPara->status.variNum < MAX_VARI_NUM){
|
||||
sysPara->status.vars[sysPara->status.variNum].startColPos = i+(sysPara->status.addSpace?i:0)+textItemPosX;
|
||||
sysPara->status.vars[sysPara->status.variNum].endRowPos = j+textItemPosY;
|
||||
//qDebug()<<"sysPara->status.variNum:"<<sysPara->status.variNum;
|
||||
//qDebug()<<"startColPos:"<<sysPara->status.vars[sysPara->status.variNum].startColPos;
|
||||
//qDebug()<<"endRowPos:"<<sysPara->status.vars[sysPara->status.variNum].endRowPos;
|
||||
if(varLastRow<j+1)
|
||||
varLastRow=j+1;
|
||||
sysPara->status.variNum ++;
|
||||
textvariNum++;
|
||||
i+=5;//scene 每一行可能都包含变量
|
||||
//qDebug()<<"VARr:"<<TempVarNum<<i<<j;
|
||||
//gItem = pPicScene->itemAt(i,j+firstRow);
|
||||
//picText_var[i]= (PicTextItem*) gItem;
|
||||
//picText_var_hash.insert(picText_var[i],i);
|
||||
}
|
||||
else
|
||||
{
|
||||
textvariNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( ((rgb & 0xfffff0) == 0x00ff10) || ((rgb & 0xfffff0) == 0x00ff20) ||((rgb & 0xfffff0) == 0x00ff30) ){
|
||||
// 0xff00ff01(DMT) 0xff00ff02(QR) 0xff00ff03(BAR)
|
||||
//qDebug()<<"FLAG:"<<i<<j+1<<QString().sprintf("%08X", rgb);
|
||||
if(sysPara->status.QRvariNum>=4)continue;
|
||||
if((rgb & 0x00ffff0) == 0x00ff10) { //MDT
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].type=MDT;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].countEn=1;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].Counter=sysPara->status.productCnt;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].startColPos=i+(sysPara->status.addSpace?i:0)+textItemPosX;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].endRowPos=j+1+textItemPosY;
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
sysPara->status.QRvariNum++;
|
||||
}
|
||||
else if((rgb & 0x00ffff0) == 0x00ff20) { //QR
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].type=QR;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].countEn=1;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].Counter=sysPara->status.productCnt;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].startColPos=i+(sysPara->status.addSpace?i:0)+textItemPosX;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].endRowPos=j+1+textItemPosY;
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
sysPara->status.QRvariNum++;
|
||||
}
|
||||
else if((rgb & 0x00fffff0) == 0x00ff30) { //BAR
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].type=BAR;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].countEn=1;
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].Counter=sysPara->status.productCnt;
|
||||
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].startColPos=i+(sysPara->status.addSpace?i:0)+textItemPosX;
|
||||
|
||||
sysPara->print.QRvars[sysPara->status.QRvariNum].endRowPos=j+1+textItemPosY;
|
||||
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
sysPara->status.QRvariNum++;
|
||||
|
||||
}
|
||||
if(sysPara->status.QRvariNum>=4)sysPara->status.QRvariNum=4;
|
||||
|
||||
}
|
||||
//else if((rgb & 0xfffff0)==0xff00f0)
|
||||
else if((rgb & 0x0000ffff)==EXPIRY_VARI_RECONISE)
|
||||
{ // 有效期变量 : 处理变量, 查找左下角,因为同一行的左下角是对齐的
|
||||
//qDebug()<<"found EXPIRY_VARI_RECONISE";
|
||||
bool foundExVar=0;
|
||||
if(j>0){
|
||||
QRgb r_rgb = textImage.pixel(i,j + firstRow+1);
|
||||
if(((r_rgb & 0x0000ffff) != EXPIRY_VARI_RECONISE )){foundExVar =1;}
|
||||
}
|
||||
if(foundExVar)
|
||||
{
|
||||
//if(sysPara->status.ExpiryVarNum <2)
|
||||
{
|
||||
//if(sysPara->print.ExpiryVar.endRowPos==0)
|
||||
if(sysPara->status.ExpiryVarNum == 0)
|
||||
{
|
||||
sysPara->status.ExpiryVarNum ++;
|
||||
}
|
||||
sysPara->print.ExpiryVar.startColPos = i+(sysPara->status.addSpace?i:0)+textItemPosX;
|
||||
sysPara->print.ExpiryVar.endRowPos = j+textItemPosY;
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
|
||||
i+=10;
|
||||
//qDebug()<<"ExpiryVar ixj:"<<i<<"x"<<j + firstRow;
|
||||
//qDebug()<<"qqqq textItemPosY:"<<textItemPosY;
|
||||
//qDebug()<<"qqqq sysPara->print.ExpiryVar.endRowPos:"<<sysPara->print.ExpiryVar.endRowPos;
|
||||
}
|
||||
//else TempVarNum++;
|
||||
//dat[MAX_PRINT_ROW_BYTE_NUM*i + j/8] |= 1 << (j%8); //画黑点
|
||||
}
|
||||
}
|
||||
else if((rgb & 0xfffff0)==0xff0cf0)
|
||||
{ // 有效期变量 : 处理变量, 查找左下角,因为同一行的左下角是对齐的
|
||||
|
||||
bool foundExVar=0;
|
||||
if(j>0){
|
||||
QRgb r_rgb = textImage.pixel(i,j + firstRow+1);
|
||||
if((r_rgb & 0xfffff0) != 0xff0cf0 ){foundExVar =1;}
|
||||
}
|
||||
if(foundExVar)
|
||||
{
|
||||
//qDebug()<<"found CurDateVar";
|
||||
//if(sysPara->status.ExpiryVarNum <2)
|
||||
{
|
||||
//if(sysPara->print.CurDateVar.endRowPos==0)
|
||||
if(sysPara->status.CurrDateVariNum == 0)
|
||||
{
|
||||
sysPara->status.CurrDateVariNum ++;
|
||||
//setRunStatus(QString("CurrDateVariNum(%1)").arg(sysPara->status.CurrDateVariNum));
|
||||
}
|
||||
sysPara->print.CurDateVar.startColPos = i+(sysPara->status.addSpace?i:0)+textItemPosX;
|
||||
sysPara->print.CurDateVar.endRowPos = j + textItemPosY;
|
||||
//qDebug()<<"CurDateVar ixj:"<<i<<"x"<<j + firstRow;
|
||||
//qDebug()<<"sysPara->print.CurDateVar.endRowPos:"<<sysPara->print.CurDateVar.endRowPos;
|
||||
if(varLastRow<j+1) varLastRow=j+1;
|
||||
|
||||
i+=10;
|
||||
//j++;
|
||||
}
|
||||
//else TempVarNum++;
|
||||
//dat[MAX_PRINT_ROW_BYTE_NUM*i + j/8] |= 1 << (j%8); //画黑点
|
||||
}
|
||||
}
|
||||
|
||||
if(j > sysPara->status.currPrintRow) {
|
||||
sysPara->status.currPrintRow = j+textItemPosY;
|
||||
}
|
||||
}/*判断alpha end*/
|
||||
}
|
||||
}
|
||||
//qDebug()<<"ExpiryVarNum:"<<sysPara->status.ExpiryVarNum;
|
||||
//===================一般变量=====================
|
||||
//myvariNum = 0;
|
||||
QString textVariPattern = "<img src=\":/(\\d*)/(\\d*)/../image/digitalWidth(\\d*).bmp\" width=\"(\\d*)\" height=\"(\\d*)\" />";
|
||||
QRegExp textrx(textVariPattern);
|
||||
QString textHtml = picText->toHtml();
|
||||
int from = 0;
|
||||
//int myvariNum=0;
|
||||
while(from < textHtml.size() && from != -1){
|
||||
from = textHtml.indexOf(textrx,from);
|
||||
|
||||
if(from != -1){//找到匹配的
|
||||
//qDebug()<<"found variable";
|
||||
from ++;
|
||||
//if(myvariNum < textvariNum)
|
||||
if(myvariNum < sysPara->status.variNum)
|
||||
{
|
||||
sysPara->status.vars[myvariNum].digitalNum = textrx.cap(3).toInt(&ok);//第二个匹配,数字到个数
|
||||
sysPara->status.vars[myvariNum].bold = (sysPara->status.vars[myvariNum].digitalNum%100) == 75;
|
||||
if(sysPara->status.vars[myvariNum].bold)
|
||||
sysPara->status.vars[myvariNum].digitalNum = sysPara->status.vars[myvariNum].digitalNum/100;
|
||||
|
||||
sysPara->status.vars[myvariNum].type = textrx.cap(2).toInt(&ok);//第一个匹配
|
||||
|
||||
sysPara->status.vars[myvariNum].width = textrx.cap(4).toInt(&ok)*(sysPara->status.addSpace?2:1);
|
||||
sysPara->status.vars[myvariNum].height = textrx.cap(5).toInt(&ok);
|
||||
//qDebug()<<"myvariNum endRowPos:"<<sysPara->status.vars[myvariNum].endRowPos;
|
||||
//qDebug()<<"myvariNum height:"<<sysPara->status.vars[myvariNum].height;
|
||||
sysPara->status.vars[myvariNum].startRowPos = sysPara->status.vars[myvariNum].endRowPos - sysPara->status.vars[myvariNum].height+1;
|
||||
//sysPara->status.vars[myvariNum].startRowPos = sysPara->status.vars[myvariNum].endRowPos - sysPara->status.vars[myvariNum].height;
|
||||
//qDebug()<<"start row:"<<sysPara->status.vars[myvariNum].startRowPos;
|
||||
if(sysPara->status.vars[myvariNum].startRowPos<0)
|
||||
sysPara->status.vars[myvariNum].startRowPos=0;
|
||||
|
||||
int item_x_start_pos = sysPara->status.vars[myvariNum].startColPos;
|
||||
int item_x_end_pos = item_x_start_pos + sysPara->status.vars[myvariNum].width ;
|
||||
if(item_x_end_pos > (MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide))
|
||||
item_x_end_pos = MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide;
|
||||
int item_y_start_pos = sysPara->status.vars[myvariNum].startRowPos;
|
||||
int item_y_end_pos = sysPara->status.vars[myvariNum].endRowPos+1 ;
|
||||
if(item_y_start_pos < 0)
|
||||
item_y_start_pos = 0;
|
||||
for(int i = item_x_start_pos; i < item_x_end_pos; i++){
|
||||
for(int j = item_y_start_pos; j < item_y_end_pos; j++){
|
||||
dat[MAX_PRINT_ROW_BYTE_NUM*(i+(sysPara->status.addSpace?0:0)) + j/8] &= ~(1 << (j%8)); //将画点取消掉
|
||||
dat[MAX_PRINT_ROW_BYTE_NUM*(i+(sysPara->status.addSpace?0:0)) + j/8] &= ~(1 << (j%8));
|
||||
}
|
||||
}
|
||||
sysPara->status.vars[myvariNum].height = textrx.cap(5).toInt(&ok)-1;
|
||||
if(sysPara->status.vars[myvariNum].height>16 ){
|
||||
if(sysPara->status.vars[myvariNum].height==24)
|
||||
;
|
||||
else {
|
||||
if(sysPara->status.vars[myvariNum].startRowPos)
|
||||
{
|
||||
sysPara->status.vars[myvariNum].endRowPos--;
|
||||
sysPara->status.vars[myvariNum].startRowPos--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(sysPara->status.vars[myvariNum].type == RANDOMNUM)
|
||||
{
|
||||
//qDebug()<<"RAND:"<<sysPara->status.vars[myvariNum].type<< sysPara->status.vars[myvariNum].digitalNum;
|
||||
sysPara->status.RandomDigitNum = sysPara->status.vars[myvariNum].digitalNum;
|
||||
}
|
||||
int pixelSize = Public::derivePixelSizeFromHeight(sysPara->status.vars[myvariNum].height);
|
||||
|
||||
//qDebug()<<"MainWindows"<<sysPara->status.vars[myvariNum].height<<pixelSize;
|
||||
|
||||
sysPara->status.vars[myvariNum].letterSpace = 0;
|
||||
if(sysPara->status.vars[myvariNum].digitalNum){ //算出letterspace
|
||||
QFont font;
|
||||
//font.setFamily(Public::getFontFamily(pixelSize));
|
||||
font.setFamily(Public::getFontFamily(pixelSize,sysPara->status.vars[myvariNum].type )); // 20160812
|
||||
//pixelSize==7? font.setFamily(ui->textEditOption->getLabelFontFamily()->text()):font.setFamily(Public::getFontFamily(pixelSize, 0));
|
||||
font.setPixelSize(pixelSize);
|
||||
font.setWeight(sysPara->status.vars[myvariNum].bold?QFont::Bold:QFont::Normal);
|
||||
//font.setLetterSpacing(QFont::AbsoluteSpacing,sysPara->para.textEditCharSpace);
|
||||
QFontMetrics fontMetrics(font);
|
||||
int charWidth = (fontMetrics.width("0123456789"))/10 ;
|
||||
// sysPara->status.vars[myvariNum].letterSpace = sysPara->para.textEditCharSpace;
|
||||
sysPara->status.vars[myvariNum].letterSpace = picText->letterSpace();
|
||||
//sysPara->status.vars[myvariNum].letterSpace =
|
||||
//sysPara->status.vars[myvariNum].width/sysPara->status.vars[myvariNum].digitalNum/(sysPara->status.addSpace?2:1) - charWidth;
|
||||
}
|
||||
myvariNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//==========================一般变量结束=======================
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
generateCharRamData();
|
||||
if(sysPara->status.currPrintRow>MAX_PRINT_ROW_NUM-1)sysPara->status.currPrintRow=MAX_PRINT_ROW_NUM-1;
|
||||
bool found=0;
|
||||
|
||||
lastRow = sysPara->status.currPrintRow;
|
||||
//qDebug()<<"lastRow:"<<lastRow;
|
||||
for(int j = sysPara->status.currPrintRow; j >2 ; j--){ //计算首行位置
|
||||
for(int i = 0; i < coldot; i++){
|
||||
if(dat[MAX_PRINT_ROW_BYTE_NUM*i + j/8] & (1 << (j%8))){
|
||||
lastRow = j+1;
|
||||
found=1;//qDebug()<<"fOUND:"<<i<<j<<dat[MAX_PRINT_ROW_BYTE_NUM*i + j/8]<<sysPara->status.currPrintRow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
break;
|
||||
}
|
||||
if(lastRow>MAX_PRINT_ROW_NUM-1)lastRow = MAX_PRINT_ROW_NUM-1;
|
||||
if(lastRow<varLastRow)lastRow= varLastRow-1;//在场景模式下,变量的最低一行并不一定是打印的最后一行
|
||||
|
||||
if(lastRow<1) lastRow =1;
|
||||
sysPara->status.currPrintRow =lastRow;
|
||||
PicTextItem *picText = qgraphicsitem_cast<PicTextItem*>(item);
|
||||
if(!picText)
|
||||
continue;
|
||||
|
||||
qDebug() << "Item propertices: ";
|
||||
qDebug() << picText->pos();
|
||||
qDebug() << picText->boundingRect();
|
||||
QXmlStreamAttributes attrs;
|
||||
picText->saveAttrs(attrs);
|
||||
for(auto attr : attrs) {
|
||||
qDebug() << attr.name() << ": " << attr.value();
|
||||
}
|
||||
|
||||
if(sysPara->status.QRvariNum) {
|
||||
// onUpdateDispQRCode(1);
|
||||
const QRectF itemSceneRect = item->sceneBoundingRect();
|
||||
const QRectF clippedSceneRect = itemSceneRect.intersected(contentRect);
|
||||
if(clippedSceneRect.isEmpty())
|
||||
continue;
|
||||
|
||||
const QRect itemRect = clippedSceneRect.translated(-contentRect.topLeft()).toAlignedRect();
|
||||
const QRectF sourceRect = clippedSceneRect;
|
||||
|
||||
if(picText && picText->sourceType() == SourceType::COUNTER) {
|
||||
PicCounterItem* counterItem = qgraphicsitem_cast<PicCounterItem*>(picText);
|
||||
if(!counterItem)
|
||||
continue;
|
||||
|
||||
if(sysPara->status.variNum >= 8)
|
||||
continue;
|
||||
|
||||
int varI = sysPara->status.variNum;
|
||||
auto& varPara = sysPara->status.vars[varI];
|
||||
varPara.type = int(counterItem->counterType());
|
||||
varPara.digitalNum = counterItem->digitalNum();
|
||||
varPara.width = itemRect.width();
|
||||
varPara.height = itemRect.height();
|
||||
varPara.startColPos = itemRect.left();
|
||||
varPara.endRowPos = itemRect.bottom() + 1;
|
||||
varPara.startRowPos = itemRect.top();
|
||||
varPara.currVal = 0;
|
||||
varPara.bold = 0;
|
||||
varPara.letterSpace = counterItem->letterSpace();
|
||||
|
||||
++sysPara->status.variNum;
|
||||
|
||||
// // 将变量序号、类型、数字个数、大小位置打印到日志
|
||||
// LogInfo::setRunStatusText("Variable " + QString::number(varI) + ": type=" + QString::number(varPara.type) +
|
||||
// "\n digitalNum=" + QString::number(varPara.digitalNum) +
|
||||
// "\n width=" + QString::number(varPara.width) +
|
||||
// "\n height=" + QString::number(varPara.height) +
|
||||
// "\n startColPos=" + QString::number(varPara.startColPos) +
|
||||
// "\n endRowPos=" + QString::number(varPara.endRowPos) +
|
||||
// "\n startRowPos=" + QString::number(varPara.startRowPos) +
|
||||
// "\n letterSpace=" + QString::number(varPara.letterSpace));
|
||||
}
|
||||
int wmax = sysPara->status.currPrintRow;
|
||||
sysPara->status.currAlterPrintRow = sysPara->status.currPrintRow/2;
|
||||
if(sysPara->para.alterPrint.enable<1) sysPara->para.AlterMode=0;
|
||||
else {
|
||||
if(sysPara->para.AlterMode==0)sysPara->para.AlterMode=1;
|
||||
wmax = sysPara->status.currAlterPrintRow;
|
||||
pPicScene->render(&painter, itemRect, sourceRect);
|
||||
}
|
||||
/*-------------------------------切换到显示窗口-----------------------------------*/
|
||||
|
||||
qDebug() << "currPrintCol: " << sysPara->status.currPrintCol;
|
||||
LogInfo::setRunStatusText("currPrintCol: " + QString::number(sysPara->status.currPrintCol));
|
||||
LogInfo::setRunStatusText("currPrintRow: " + QString::number(sysPara->status.currPrintRow));
|
||||
LogInfo::setRunStatusText(QString("Items bounding rect: {%1, %2}").arg(sceneRect.width()).arg(sceneRect.height()));
|
||||
|
||||
// sysPara->status.currPrintRow = sceneRect.height();
|
||||
sysPara->status.currPrintCol = sceneRect.width();
|
||||
|
||||
auto rows = sysPara->para.AlterMode?sysPara->status.currAlterPrintRow : sysPara->status.currPrintRow;
|
||||
rows = std::max(rows, (m_PrintDisplay->parentWidget()->height() / m_PrintDisplay->currScaleRatio()));
|
||||
auto cols = sysPara->status.currPrintCol;
|
||||
cols = std::max(cols, (m_PrintDisplay->parentWidget()->width() / m_PrintDisplay->currScaleRatio()));
|
||||
m_PrintDisplay->setDisplaySize(cols, rows);
|
||||
m_PrintDisplay->update();
|
||||
}
|
||||
previewFlag=0;
|
||||
|
||||
sysPara->status.currPrintRow = sceneRect.height();
|
||||
sysPara->status.currPrintCol = sceneRect.width();
|
||||
|
||||
imageToPrintData(image, 0, 0);
|
||||
|
||||
// /*--------------------------------------------------------------------------*/
|
||||
generateCharRamData();
|
||||
if(sysPara->status.currPrintRow>MAX_PRINT_ROW_NUM-1)sysPara->status.currPrintRow=MAX_PRINT_ROW_NUM-1;
|
||||
sysPara->status.currPrintRow = qMin(sysPara->status.currPrintRow, MAX_PRINT_ROW_NUM-1);
|
||||
|
||||
// 计算末行位置
|
||||
bool found = false;
|
||||
int lastRow = sysPara->status.currPrintRow;
|
||||
for(int j = sysPara->status.currPrintRow; j > 2 ; j--){
|
||||
for(int i = 0; i < coldot; i++){
|
||||
if(dat[MAX_PRINT_ROW_BYTE_NUM*i + j/8] & (1 << (j%8))){
|
||||
lastRow = j+1;
|
||||
found = true;//qDebug()<<"fOUND:"<<i<<j<<dat[MAX_PRINT_ROW_BYTE_NUM*i + j/8]<<sysPara->status.currPrintRow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
break;
|
||||
}
|
||||
|
||||
sysPara->status.currPrintRow = qBound(1, lastRow, MAX_PRINT_ROW_NUM - 1);
|
||||
|
||||
int wmax = sysPara->status.currPrintRow;
|
||||
sysPara->status.currAlterPrintRow = sysPara->status.currPrintRow/2;
|
||||
if(sysPara->para.alterPrint.enable<1) sysPara->para.AlterMode=0;
|
||||
else {
|
||||
if(sysPara->para.AlterMode==0)sysPara->para.AlterMode=1;
|
||||
wmax = sysPara->status.currAlterPrintRow;
|
||||
}
|
||||
/*-------------------------------切换到显示窗口-----------------------------------*/
|
||||
|
||||
qDebug() << "currPrintCol: " << sysPara->status.currPrintCol;
|
||||
LogInfo::setRunStatusText("currPrintCol: " + QString::number(sysPara->status.currPrintCol));
|
||||
LogInfo::setRunStatusText("currPrintRow: " + QString::number(sysPara->status.currPrintRow));
|
||||
LogInfo::setRunStatusText(QString("Items bounding rect: {%1, %2}").arg(sceneRect.width()).arg(sceneRect.height()));
|
||||
|
||||
// sysPara->status.currPrintRow = sceneRect.height();
|
||||
sysPara->status.currPrintCol = sceneRect.width();
|
||||
|
||||
auto rows = sysPara->para.AlterMode?sysPara->status.currAlterPrintRow : sysPara->status.currPrintRow;
|
||||
rows = std::max(rows, (m_PrintDisplay->parentWidget()->height() / m_PrintDisplay->currScaleRatio()));
|
||||
auto cols = sysPara->status.currPrintCol;
|
||||
cols = std::max(cols, (m_PrintDisplay->parentWidget()->width() / m_PrintDisplay->currScaleRatio()));
|
||||
m_PrintDisplay->setDisplaySize(cols, rows);
|
||||
m_PrintDisplay->update();
|
||||
}
|
||||
|
||||
void MainWidget::handleEmptySize()
|
||||
@@ -2387,7 +2061,6 @@ void MainWidget::handleEmptySize()
|
||||
// pPicScene->render(&emptyPainter, QRectF(), QRectF(0, 0, emptySize.width(), emptySize.height()));
|
||||
|
||||
// 初始化打印参数,避免空场景导致的参数异常
|
||||
previewFlag = 1;
|
||||
sysPara->status.currPrintRow = 0;
|
||||
sysPara->status.currPrintCol = 0; // emptySize.width();
|
||||
sysPara->status.variNum = 0;
|
||||
@@ -2405,7 +2078,6 @@ void MainWidget::handleEmptySize()
|
||||
rows = std::max(rows, (m_PrintDisplay->parentWidget()->height() / m_PrintDisplay->currScaleRatio()));
|
||||
m_PrintDisplay->setDisplaySize(m_PrintDisplay->parentWidget()->width() / m_PrintDisplay->currScaleRatio(), rows);
|
||||
m_PrintDisplay->update();
|
||||
previewFlag = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2873,6 +2545,7 @@ void MainWidget::UpdateUIVersion(){
|
||||
|
||||
QString VernonBach;
|
||||
VernonBach.sprintf("A%d.%d.%02d%s%s", UP_PRINTER_MAJOR_VER, UP_PRINTER_MINOR_VER,UP_PRINTER_RIVISION_VER,SUB_VERSION,SUB_RFID);
|
||||
VernonBach = VernonBach + (QString) Public::DateToString(__DATE__)+"_"+ QString(__TIME__)+"_";
|
||||
|
||||
QString Mac = QString::number(sysPara->status.machineMac);
|
||||
LogInfo::setRunStatusText(QString("Mac:%1").arg(Mac));
|
||||
|
||||
+1
-3
@@ -123,7 +123,7 @@ public:
|
||||
|
||||
QTimer *timerShowItem,*timerPowerOff;
|
||||
|
||||
void SendPrintDataToFpga(unsigned char alterMode, int startCols = -1, int size = -1);
|
||||
void SendPrintDataToFpga(unsigned char alterEnable, bool isUpdate = false);
|
||||
|
||||
void updatePrintDisplayLabel();
|
||||
|
||||
@@ -155,8 +155,6 @@ private:
|
||||
QToolButton* m_LeftBtn;
|
||||
PrintTextDisplay* m_PrintDisplay;
|
||||
|
||||
|
||||
bool previewFlag;
|
||||
int r_ExpiryDay;
|
||||
QTimer *airPushTimer;
|
||||
|
||||
|
||||
+328
-330
File diff suppressed because it is too large
Load Diff
+6
-2
@@ -444,6 +444,8 @@ void TestPrintWidget::openWorkFile(QString filePath){
|
||||
}
|
||||
}
|
||||
|
||||
pViewer->centerOn(0, 0);
|
||||
|
||||
if(m_printSetting) {
|
||||
m_printSetting->setModel(m_printSettingModel);
|
||||
}
|
||||
@@ -661,10 +663,12 @@ void TestPrintWidget::showEvent(QShowEvent *event)
|
||||
pPicScene->update();
|
||||
auto sceneRect = pPicScene->sceneRect();
|
||||
// qreal sceneHeight = boundingRect.height() > (qreal)(sysPara->para.canvasHeight) ? SCENE_MAX_HEIGHT : (qreal)(sysPara->para.canvasHeight);
|
||||
qreal sceneHeight = qMin(qreal(SCENE_MAX_HEIGHT), (qreal)(sysPara->para.canvasHeight));
|
||||
sceneRect.setHeight(sceneHeight);
|
||||
int sceneHeight = qMin(int(SCENE_MAX_HEIGHT), (int)(sysPara->para.canvasHeight));
|
||||
sceneRect.setHeight((qreal)(sceneHeight));
|
||||
pPicScene->setSceneRect(sceneRect);
|
||||
|
||||
// TODO:: 添加代码,只在sceneHeight高度为32时,才显示 字体大小选择框中的 32 dot选项
|
||||
|
||||
// 以高度为基准 最大化显示场景到 视口
|
||||
auto viewportHeight = pViewer->viewport()->height();
|
||||
QTransform transform = pViewer->transform();
|
||||
|
||||
Reference in New Issue
Block a user