#include "mainwidget.h" #include #include #include #include "Public.h" #include #include #include #include #include #include #include #include #include #include #include #include "DevOp.h" #include "Public.h" #include "scene/picscene.h" #include #include "MyInputMethod.h" #include #include #include #include #include "VerBVersion.h" #include #include #include "scene/PicDateItem.h" #include "scene/PicScheduleShiftItem.h" #include "scene/piccodeitem.h" #include "scene/PicCounterItem.h" #include #include #include #include #include "MainWidget.h" #include "scene/ItemCommon.h" #include "StateMachine/PrinterStateManager.h" extern MyInputMethod *myInputMethod; unsigned char test_flag,open_close; #pragma execution_character_set("utf-8") MainWidget::MainWidget(QWidget* parent) : QWidget(parent) { // 加载UI文件 ui.setupUi(this); // 关联成员变量到UI控件 m_EditBtn = ui.m_EditBtn; m_AddBtn = ui.m_AddBtn; m_MainBtn = ui.m_MainBtn; m_ManageBtn = ui.m_ManageBtn; m_MsgBtn = ui.m_MsgBtn; m_PrintDisplay = ui.widgetPrintTextDisplay; m_CloseBtn = ui.m_CloseBtn; m_StopBtn = ui.m_StopBtn; m_StartBtn = ui.m_StartBtn; // m_ToolBtn = ui.m_ToolBtn; m_RightBtn = ui.m_RightBtn; m_LeftBtn = ui.m_LeftBtn; m_PrintDisplay->update(); pushButtonFlag = true; m_2sFlag = false; // 初始化信号槽连接 init(); m_fileManageWidget = new FileManageWidget(); // ui.labelRunStatus->setWordWrap(true); // ui.sub3->installEventFilter(this); // ui.fra_state->installEventFilter(this); ui.labelTotalProductCnt->hide(); ui.lb_counter->hide(); changeHighLight(false); enablePrintButton(false); QWidget* viewport = ui.scrollArea->viewport(); // 捕获鼠标左键拖动手势(桌面端) QScroller::grabGesture(viewport, QScroller::LeftMouseButtonGesture); // 如需同时支持触摸屏,可加上触屏手势 QScroller::grabGesture(viewport, QScroller::TouchGesture); QScroller* scroller = QScroller::scroller(viewport); QScrollerProperties properties = scroller->scrollerProperties(); // 启用惯性滚动 properties.setScrollMetric(QScrollerProperties::DecelerationFactor, 0.7); // 防止过小的移动被误判为拖拽 properties.setScrollMetric(QScrollerProperties::DragStartDistance, 0.002); scroller->setScrollerProperties(properties); scroller->grabGesture(ui.scrollArea->viewport(), QScroller::LeftMouseButtonGesture); connect(ui.btn_newFile, &QPushButton::clicked, this, &MainWidget::newFileAcquired); m_reclaimOpenBtnFlashTimer = new QTimer(this); connect(m_reclaimOpenBtnFlashTimer, &QTimer::timeout, this, &MainWidget::onReclaimOpenBtnFlashTimerTimeout); m_reclaimOpenBtnFlashTimer->setInterval(500); m_nozzleStateMarqueeTimer = new QTimer(this); m_nozzleStateMarqueeTimer->setInterval(30); connect(m_nozzleStateMarqueeTimer, &QTimer::timeout, this, &MainWidget::onNozzleStateMarqueeTimeout); if (ui.lb_nozzleState) { ui.lb_nozzleState->installEventFilter(this); ui.lb_nozzleState->setText(" "); } } MainWidget::~MainWidget() { delete m_fileManageWidget; } void MainWidget::init() { airPushTimer = new QTimer(this); connect(airPushTimer, SIGNAL(timeout()), this, SLOT(airPushingProcess())); timerPowerOff = new QTimer(this); connect(timerPowerOff,SIGNAL(timeout()),this,SLOT(sendPowerOffCmd())); // 信号槽连接 connect(m_EditBtn, &QPushButton::clicked, this, &MainWidget::buttonClickedSlot); connect(m_AddBtn, &QPushButton::clicked, this, &MainWidget::buttonClickedSlot); connect(m_CloseBtn, &QPushButton::clicked, this, &MainWidget::buttonClickedSlot); connect(m_MainBtn,&QPushButton::clicked,this,&MainWidget::buttonClickedSlot); connect(m_MsgBtn,&QPushButton::clicked,this,&MainWidget::buttonClickedSlot); if (!m_setNumDlg){ m_setNumDlg = new SetNumDlg(this); } connect(m_setNumDlg, &SetNumDlg::sig_setNum, this, &MainWidget::slt_setNum); connect(m_setNumDlg, &SetNumDlg::sig_clearCnt, this, &MainWidget::slt_clearCnt); } void MainWidget::buttonClickedSlot() { QPushButton* btn = qobject_cast(sender()); if (btn == m_EditBtn) { emit sendButtonClickedSignal(1); } else if (btn == m_AddBtn) { emit sendButtonClickedSignal(2); } else if (btn == m_CloseBtn) { // emit sendButtonClickedSignal(3); _on_pushButtonPowerOff_pressed(true); } else if(btn == m_MainBtn){ emit sendButtonClickedSignal(4); } else if(btn == m_MsgBtn){ emit sendButtonClickedSignal(5); } } QStringList stringListRecive; void MySleep(unsigned int msec); void MySleep(unsigned int msec) { QTime dieTime = QTime::currentTime().addMSecs(msec); while( QTime::currentTime() < dieTime ) QCoreApplication::processEvents(QEventLoop::AllEvents, 100); } bool MainWidget::generatePrintContent(PicScene *scene) { if(!scene) { qWarning() << "Scene is empty!"; return false; } if(this->pPicScene) { pPicScene->deleteLater(); pPicScene = nullptr; } this->pPicScene = scene; onPreviewScene(); SendPrintDataToFpga(0); return true; } void MainWidget::bindSysPara(SysPara *sysPara){ this->sysPara = sysPara; // ui->textEditOption->bindSysPara(sysPara); m_PrintDisplay->bindSysPara(sysPara); #ifdef _2DCODE_ // barcode->bindSysPara(sysPara); // dlgqrcode->setSysPara(sysPara); // dlgqrcode->barCodeFlag = this->sysPara->para.qrOption.barCodeFlag; // dlgqrcode->SetOption((qrOption_t*)&sysPara->para.qrOption); #endif #ifdef PICSCENE // ui->senceEditOption->bindSysPara(sysPara); #endif } void MainWidget::_on_pushButtonPowerOff_pressed(bool notice) { if(!sysPara) return; // 回收槽检查 if(sysPara->status.currReclaimTankPos != 0) { QMessageBox::StandardButton ret = QMessageBox::Ok; if(notice) { ret = QMessageBox::warning(this, tr("警告"), tr("回收槽未关,是否关闭回收槽后关机!"), QMessageBox::Ok | QMessageBox::Cancel); } if (!notice || ret == QMessageBox::Ok) { system((char *)((QString("mkdir %1").arg(TESTDIR)).toLatin1().data())); system((char *)((QString("cp %1/*.bin %2/. ").arg(PARA_ROOT_DIR).arg(TESTDIR)).toLatin1().data())); //先备份UP* sysPara->status.reclaimCloseCnt=10; //on_pushButtonStopPrint_pressed(); on_m_StopBtn_clicked(); on_m_LeftBtn_clicked(); //on_pushButtonReclaimTankClose_pressed(); sysPara->status.powerOffAppending = true; setReclaimCloseBtnStatus(false); setReclaimOpenBtnStatus(false); } } else { QMessageBox::StandardButton ret = QMessageBox::Ok; if(notice) { ret = QMessageBox::warning(this, tr("警告"), tr("是否确认关机?"), QMessageBox::Ok | QMessageBox::Cancel); } if (!notice || ret == QMessageBox::Ok){ sysPara->status.powerOffAppending = true; checkForPowerOff(); } } } /* * 关机前务必保存参数 * */ void MainWidget::checkForPowerOff(){ if(sysPara->status.powerOffAppending){ if(!sysPara->status.selfCheckDone) sysPara->status.selfCheckDone = true; this->setDisabled(true); emit setDisableAll(); ////////关机时提高转速和回收泵压力,粘度泵和循环阀///// quint16 gearPumpValue_backup = sysPara->para.gearPumpValue; int reclaimPumpPWMWidth_backup = sysPara->para.reclaimPumpPWMWidth;; if(!(sysPara->status.statWarn & WARN_STATUS_INK_WARN)) { if(!TEST_MODE && sysPara->para.flagOfReclaimPumEnable){ for(int i=25;i>21;i--) { if(i == 25){ sysPara->status.isPumpValveControledByHand = true; //停止自动 sysPara->devOp->controlInkValve(true); sysPara->devOp->controlInkValvePWM(true); sysPara->devOp->controlReclaimPump(true,true); sysPara->devOp->controlViscosityPump(true); sysPara->devOp->controlCycleValve(true); sysPara->para.gearPumpValue = 0; sysPara->devOp->WriteMoterPump(); } if(i == 22){ sysPara->devOp->controlInkValve(false); sysPara->devOp->controlInkValvePWM(false); } this->setRunStatus(tr("正在准备关机,请等待%1秒...").arg(i*2), false); MySleep(2000); } } sysPara->devOp->controlReclaimTankOpen(true); sysPara->status.isPumpValveControledByHand = true; //停止自动 if(sysPara->para.gearPumpEnable ){ if(!sysPara->para.flagOfReclaimPumEnable){ sysPara->para.gearPumpValue = 360; sysPara->devOp->WriteMoterPump(); } else{ sysPara->devOp->controlReclaimPump(true,false); sysPara->para.gearPumpValue = 0; sysPara->devOp->WriteMoterPump(); } } else{ sysPara->para.reclaimPumpPWMWidth = 95; sysPara->devOp->controlReclaimPump(true,true); } if(!sysPara->devOp->isViscosityPumpOpen()) sysPara->devOp->controlViscosityPump(true); sysPara->devOp->controlCycleValve(true); sysPara->devOp->controlInkValve(false); //关供墨 sysPara->devOp->controlInkValvePWM(false); //关供墨 if(!TEST_MODE){ for(int i=14;i>7;i--) { if(i==13) sysPara->devOp->controlReclaimTankOpen(false); this->setRunStatus(tr("正在准备关机,请等待%1秒...").arg(i), false); MySleep(3000); } } if(!sysPara->status.lostCommuFlag){ sysPara->para.calandar_and_dat.cnt1CurrValue = QString::number(sysPara->status.calandar_and_dat.cnt1CurrValue,16).toInt(); sysPara->para.calandar_and_dat.cnt2CurrValue = QString::number(sysPara->status.calandar_and_dat.cnt2CurrValue,16).toInt(); sysPara->para.Counter3.cnt3CurrValue = QString::number(sysPara->status.Status_Counter3.cnt3CurrValue,16).toInt(); updateTotalCnt(0); sysPara->saveParaToFile(); // 关机前将相关配置保存 } if(!TEST_MODE){ for(int i=7;i>0;i--) { if(i == 3) sysPara->devOp->controlReclaimTankClose(true); if(i == 2){ sysPara->devOp->controlViscosityPump(false); sysPara->devOp->controlCycleValve(false); sysPara->devOp->controlReclaimPump(false,false); sysPara->para.gearPumpValue = 0; sysPara->devOp->WriteMoterPump(); } this->setRunStatus(tr("正在准备关机,请等待%1秒...").arg(i*3), false); MySleep(3000); } } } emit CloseJd(); sysPara->para.gearPumpValue=gearPumpValue_backup; sysPara->para.reclaimPumpPWMWidth = reclaimPumpPWMWidth_backup; sysPara->devOp->controlCompressPump(false); setRunStatus(tr("准备关机...")); sysPara->para.totalProductCnt +=sysPara->status.totalProductCnt; sysPara->devOp->clearProductCnt(3 | 0x10);//总产器计数器立即清零 sysPara->para.ReadFileErrorCnt=0; sysPara->para.PowerOnErrorCnt=0; if(sysPara->para.isCntSaveStateValue) { sysPara->para.cnt1CurrValue = QString::number(sysPara->status.calandar_and_dat.cnt1CurrValue,16).toInt(); sysPara->para.cnt2CurrValue = QString::number(sysPara->status.calandar_and_dat.cnt2CurrValue,16).toInt(); sysPara->para.cnt3CurrValue = QString::number(sysPara->status.Status_Counter3.cnt3CurrValue,16).toInt(); } updateTotalCnt(0); sysPara->saveParaToFile(); // 关机前将相关配置保存 sysPara->saveRFIDPara(); system("sync");//缓存同步 timerPowerOff->start(1000); } } static int numOfPowerOffCMD = 0; void MainWidget::sendPowerOffCmd(){ if(++numOfPowerOffCMD == 6){ sysPara->devOp->color_flag = 2; setRunStatus(tr("关机失败!!!")); timerPowerOff->stop(); numOfPowerOffCMD = 0; return; } sysPara->devOp->powerOff(); } void MainWidget::powerOffConfirmed(){ timerPowerOff->stop(); QProcess process; process.startDetached("poweroff"); qApp->exit(0); } void MainWidget::setRunStatus(QString str, bool enbRoll, bool warn) { //自检和关机时不显示报警logo if (warn) { if (sysPara && !sysPara->status.selfCheckDone || sysPara->status.powerOffAppending) { return; } } // 自检完成后,timerHandler中会发送停止打印的命令,导致“停止打印,自动关闭高压.”顶替掉“自检完成!!!”的情况 if(ui.lb_nozzleState->text() == qApp->translate("InkJetPrinter", "自检完成!!!") && str == qApp->translate("InkJetPrinter", "停止打印,自动关闭高压.")) { return; } // 如果禁用走马灯(enbRoll == false),直接在label上显示文本(即使过长) if (!enbRoll) { if (ui.lb_nozzleState) { // 先停止任何走马灯效果,保证文本直接显示 stopNozzleStateMarquee(); ui.lb_nozzleState->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); ui.lb_nozzleState->setText(str); ui.lb_nozzleState->update(); } return; } // 使用走马灯显示长文本 updateNozzleStateMarquee(str); } void MainWidget::stopNozzleStateMarquee() { if (m_nozzleStateMarqueeTimer && m_nozzleStateMarqueeTimer->isActive()) { m_nozzleStateMarqueeTimer->stop(); } m_nozzleStateFullText.clear(); m_nozzleStateMarqueeOffsetPx = 0; m_nozzleStateMarqueeTextWidth = 0; m_nozzleStateMarqueeGapPx = 0; m_nozzleStateMarqueeEnabled = false; if (ui.lb_nozzleState) { ui.lb_nozzleState->setText(QString()); ui.lb_nozzleState->update(); } } void MainWidget::updateNozzleStateMarquee(const QString& str) { if (!ui.lb_nozzleState) return; QString text = str; if (text.isEmpty()) { stopNozzleStateMarquee(); ui.lb_nozzleState->setText(text); return; } QFontMetrics fm(ui.lb_nozzleState->font()); const int labelWidth = ui.lb_nozzleState->contentsRect().width(); if (labelWidth <= 0 || fm.horizontalAdvance(text) <= labelWidth) { stopNozzleStateMarquee(); ui.lb_nozzleState->setText(text); return; } // 长文本循环滚动,按像素偏移绘制 m_nozzleStateFullText = text; m_nozzleStateMarqueeTextWidth = fm.horizontalAdvance(text); m_nozzleStateMarqueeGapPx = qMax(20, labelWidth / 2); m_nozzleStateMarqueeOffsetPx = 0; m_nozzleStateMarqueeEnabled = true; // 为走马灯绘制恢复居中对齐 ui.lb_nozzleState->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); ui.lb_nozzleState->setText(QString()); ui.lb_nozzleState->update(); if (!m_nozzleStateMarqueeTimer->isActive()) { m_nozzleStateMarqueeTimer->start(); } } void MainWidget::onNozzleStateMarqueeTimeout() { if (!m_nozzleStateMarqueeEnabled || !ui.lb_nozzleState) { return; } const int labelWidth = ui.lb_nozzleState->contentsRect().width(); if (labelWidth <= 0 || m_nozzleStateMarqueeTextWidth <= 0) { stopNozzleStateMarquee(); return; } const int totalWidth = m_nozzleStateMarqueeTextWidth + m_nozzleStateMarqueeGapPx; m_nozzleStateMarqueeOffsetPx += 1; if (m_nozzleStateMarqueeOffsetPx >= totalWidth) { m_nozzleStateMarqueeOffsetPx = 0; } ui.lb_nozzleState->update(); } bool MainWidget::eventFilter(QObject *watched, QEvent *event) { if (watched == ui.lb_nozzleState && m_nozzleStateMarqueeEnabled) { if (event->type() == QEvent::Paint) { QPainter painter(ui.lb_nozzleState); painter.setRenderHint(QPainter::TextAntialiasing, true); const QRect rect = ui.lb_nozzleState->contentsRect(); painter.fillRect(rect, ui.lb_nozzleState->palette().window()); painter.setPen(ui.lb_nozzleState->palette().color(QPalette::WindowText)); painter.setFont(ui.lb_nozzleState->font()); const QFontMetrics fm(ui.lb_nozzleState->font()); const int baseline = (rect.height() + fm.ascent() - fm.descent()) / 2; const int startX = rect.left() - m_nozzleStateMarqueeOffsetPx; const int textY = rect.top() + baseline; painter.drawText(startX, textY, m_nozzleStateFullText); painter.drawText(startX + m_nozzleStateMarqueeTextWidth + m_nozzleStateMarqueeGapPx, textY, m_nozzleStateFullText); return true; } } return QWidget::eventFilter(watched, event); } /* 生成字模数据 */ void MainWidget::generateCharRamData() { if(!sysPara->status.variNum) return; QTextEdit textEdit; textEdit.document()->setDocumentMargin(0); textEdit.setLineWrapMode(QTextEdit::NoWrap); int ramAddress = 0; int i; qDebug()<<"sysPara->status.variNum:"<status.variNum; for( i = 0; i < sysPara->status.variNum; i++){ vars_t *p_var = &sysPara->status.vars[i]; p_var->bassAddr = -1; if(p_var->original){ //清除原来的记录 if(p_var->dat){ free(p_var->dat); } p_var->original = false; } int width; if(p_var->bassAddr == -1){ if(sysPara->para.flagOfModuleDecimal || sysPara->para.flagOfModuleHide) width = (p_var->digitalNum)?(13*(p_var->width/p_var->digitalNum)):12; else width = (p_var->digitalNum)?(10*(p_var->width/p_var->digitalNum)):12; int width2 = width;//+(sysPara->status.addSpace?width:0); int height = p_var->height; textEdit.clear(); int DPI = textEdit.logicalDpiX(); DPI = DPI?DPI:1; //Pixel = DPI * Point / 72 if(sysPara->para.flagOfModuleDecimal || sysPara->para.flagOfModuleHide){ textEdit.insertHtml(QString("0123456789.m ") .arg(Public::getFontFamily(height,p_var->type)) // 20160812 增加横向字体 p_var->type <9 正常, p_var->type 20~28 左横 p_var->type 40~48 右横 .arg(height*96/DPI).arg(p_var->bold?600:400)); //600表示加粗,400表示普通 }else{ textEdit.insertHtml(QString("0123456789") // .arg(p_var->bold?ui->textEditOption->getFamilyName(height):(Public::getFontFamily(height,p_var->type))) // 20160812 增加横向字体 p_var->type <9 正常, p_var->type 20~28 左横 p_var->type 40~48 右横 .arg(Public::getFontFamily(height,p_var->type)) .arg(height*96/DPI)); } QFont font = textEdit.font(); font.setLetterSpacing(QFont::AbsoluteSpacing,p_var->letterSpace); textEdit.setFont(font); qDebug() << "Generate char, letter space: " << p_var->letterSpace << "font height: " << height; int imgHeight = height + 12; QSize size(width,imgHeight); QImage image(size,QImage::Format_ARGB32); image.fill(0x00ffffff); QPainter painter(&image); textEdit.show(); //如果不显示,似乎不会绘制 textEdit.document()->drawContents (&painter, image.rect()); /*将text写到pic*/ QString fileName = "/home/plg/doc/002.html"; QTextDocumentWriter writer(fileName); bool success = writer.write(textEdit.document()); textEdit.hide(); image.save(QString::number(i) + "varRam.png"); // 找到最下面的行 int lastValidRow = 0; for(int k = imgHeight - 1; k >= 0 ; k--){ for(int j = 0; j < width; j ++){ QRgb rgb = image.pixel(j,k); if(rgb&0xff000000){ lastValidRow = k + 1; break; } } if(lastValidRow != 0) break; } qDebug()<<"lastValidRow"<endRowPos<< p_var->startRowPos; int rowDiff = p_var->endRowPos - p_var->startRowPos; int firstValidRow = 0; // 变量的第一行所处的行地址 int firstValidRowDiff;// 看起来和上面的参数一样 qDebug()<<"rowDiff"<= rowDiff){ firstValidRow = lastValidRow - rowDiff; firstValidRowDiff = firstValidRow; } else { firstValidRow = 0; firstValidRowDiff = lastValidRow > rowDiff; } firstValidRow = firstValidRow >= 0?firstValidRow:0; //纠正 int rowByteNum = rowDiff/8 + ((rowDiff%8)?1:0); // 一列占用字节数 unsigned char *dat = (unsigned char *)calloc(width2,rowByteNum); for(int k = firstValidRow; k < lastValidRow; k++){ for(int j = 0; j < width; j ++){ QRgb rgb = image.pixel(j,k); int currRow = k - firstValidRowDiff; if(((rgb >> 24)&0xff) > 0x80){ // 判断是否有效的像素点 dat[rowByteNum*(j+(sysPara->status.addSpace?j:0) )+ currRow/8] |= (1<<(currRow%8)); } else{ } } } p_var->bassAddr = ramAddress; p_var->datHeight = height; p_var->datWidth = width2; p_var->rowByteNum = rowByteNum; p_var->dat = dat; p_var->original = true; p_var->currVal = -1; //相当于初始化 ramAddress += rowByteNum * width2; } } } void MainWidget::generateCharRamDataV2() { if(sysPara->status.variNum == 0) return; qDebug()<<"sysPara->status.variNum:"<status.variNum; int ramAddress = 0; int i; for( i = 0; i < sysPara->status.variNum; i++){ vars_t *p_var = &sysPara->status.vars[i]; p_var->bassAddr = -1; if(p_var->original){ //清除原来的记录 if(p_var->dat){ free(p_var->dat); } p_var->original = false; } int width; if(p_var->bassAddr == -1){ width = (p_var->digitalNum)?(10*(p_var->width/p_var->digitalNum)):12; int height = p_var->height; QString fontname = Public::getFontFamily(height,p_var->type); QFont font(fontname); // 用 0 间距,间距交给FPGA处理 font.setLetterSpacing(QFont::AbsoluteSpacing, 0); qDebug() << "Generate char, letter space: " << p_var->letterSpace << "font height: " << height; static constexpr char *NUMBERS = "0123456789"; QImage image = ItemUtils::txtToImage(NUMBERS, font, Qt::black, Qt::transparent); int imgH = image.height(); int imgW = image.width(); int rowByteNum = imgH/8 + ((imgH%8)?1:0); // 一列占用字节数 unsigned char *dat = (unsigned char *)calloc(imgW, rowByteNum); for(int k = 0; k < imgH; k++){ for(int j = 0; j < imgW; j ++){ QRgb rgb = image.pixel(j,k); int abit = ((rgb >> 24)&0xff) > 0x80 ? 1 : 0; dat[rowByteNum * j + k / 8] |= (abit << (k%8)); } } // 填充宽度表 QFontMetrics fm(font); for(int i = 0; i < 10; ++i) { p_var->widthTable[i] = fm.horizontalAdvance(NUMBERS[i]); } // 填充其他值 p_var->bassAddr = ramAddress; p_var->datHeight = imgH; p_var->datWidth = imgW; p_var->rowByteNum = rowByteNum; p_var->dat = dat; p_var->original = true; p_var->currVal = -1; //相当于初始化 ramAddress += rowByteNum * imgW; } } } QList MainWidget::variableItemsUpdate() { if(!pPicScene) { return QList(); } int totalOfProcessedDots = 0; int totalOfDatetimeNumber = 0; int nbInvaliedDatetimePreview = 0; int nbClipDatetimePreview = 0; QList 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(i); if(!item) continue; if(item->sourceType() != SourceType::DATETIME && item->sourceType() != SourceType::SCHEDULE_SHIFT && item->sourceType() != SourceType::CODE) continue; if(item->sourceType() == SourceType::DATETIME) { auto dateTimeItem = dynamic_cast(item); if(!dateTimeItem) continue; auto b = dateTimeItem->updateDatetimeStr(); if(!b) continue; } if(item->sourceType() == SourceType::SCHEDULE_SHIFT) { auto scheduleShiftItem = dynamic_cast(item); if(!scheduleShiftItem) continue; auto b = scheduleShiftItem->updateScheduleName(); if(!b) continue; } if(item->sourceType() == SourceType::CODE) { auto codeItem = dynamic_cast(item); if(!codeItem) continue; QVector 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) continue; } QImage img = item->preview(); if(img.isNull()) { ++nbInvaliedDatetimePreview; continue; } // 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; // } // 获取 item 的场景绝对坐标 const QRectF itemSceneRect = item->sceneBoundingRect(); // 与输出区域裁剪(使用绝对坐标) const QRectF clippedSceneRect = itemSceneRect.intersected(outputRect); if(clippedSceneRect.isEmpty()) continue; QRect targetRect = clippedSceneRect.toAlignedRect(); totalOfDatetimeNumber++; // 计算 item 在场景中的绝对矩形(整数对齐) QRect itemSceneAlignedRect = itemSceneRect.toAlignedRect(); // 如果 targetRect 和 item 原始场景矩形不一致,说明被 outputRect 裁剪了 if(targetRect != itemSceneAlignedRect) { // 计算裁剪偏移量:相对于 item 左上角的偏移 const int cropX = targetRect.left() - itemSceneAlignedRect.left(); const int cropY = targetRect.top() - itemSceneAlignedRect.top(); // 从 preview 图片中裁剪出对应区域 // 注意:preview 图片的尺寸等于 itemSceneAlignedRect 的尺寸(假设 preview 生成时使用了完整的 boundingRect) img = img.copy(cropX, cropY, targetRect.width(), targetRect.height()); ++nbClipDatetimePreview; } totalOfProcessedDots += imageToPrintData(img, targetRect.left(), targetRect.top()); updateAreas.append(targetRect); } if(updateAreas.isEmpty()) return updateAreas; // 把 updateAreas 里 x 轴相交或相连的矩形合并,避免某些区域重复更新而导致的串口资源浪费 std::sort(updateAreas.begin(), updateAreas.end(), [](const QRect &a, const QRect &b) { if (a.left() != b.left()) return a.left() < b.left(); return a.right() < b.right(); }); QList mergedAreas; mergedAreas.append(updateAreas.first()); for (int i = 1; i < updateAreas.size(); ++i) { QRect current = updateAreas.at(i); QRect &last = mergedAreas.last(); if (last.right() + 1 >= current.left()) { int left = qMin(last.left(), current.left()); int right = qMax(last.right(), current.right()); int top = qMin(last.top(), current.top()); int bottom = qMax(last.bottom(), current.bottom()); last = QRect(QPoint(left, top), QPoint(right, bottom)); } else { mergedAreas.append(current); } } return mergedAreas; } int MainWidget::imageToPrintData(QImage &image, int startX, int startY) { int totalOfProcessedDots = 0; if(image.isNull()) return 0; unsigned char *dat = sysPara->status.flagOfNo67FPGA ? sysPara->status.printDat_Normal : sysPara->status.printDat; int width = image.width(); int height = image.height(); int wStart = startX; for(int j = 0; j < width; j++) { unsigned char c = 0; int hStart = startY; c = dat[wStart * MAX_PRINT_ROW_BYTE_NUM + (hStart) / 8]; for(int k = 0; k < height; k++) { QRgb rgb = image.pixel(j, k); 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)); } if(hStart % 8 == 7) { dat[wStart * MAX_PRINT_ROW_BYTE_NUM + (hStart) / 8] = c; c = dat[wStart * MAX_PRINT_ROW_BYTE_NUM + (hStart + 1) / 8]; ++totalOfProcessedDots; } hStart++; } dat[wStart * MAX_PRINT_ROW_BYTE_NUM + (hStart) / 8] = c; wStart++; totalOfProcessedDots++; } return totalOfProcessedDots; } void MainWidget::enablePrintButton(bool enable){ #ifdef QT_DEBUG enable = true; #endif m_StartBtn->setEnabled(enable); m_StopBtn->setEnabled(enable); } void MainWidget::updateTotalCnt(int en) { // No50 USEING //sysPara->para.totalProductCnt += (sysPara->status.productCnt>sysPara->status.lastProductCnt)?sysPara->status.productCnt-sysPara->status.lastProductCnt: // (sysPara->status.productCnt>=0&&sysPara->status.productCnt<20)?sysPara->status.productCnt:0; //if(en) sysPara->para.totalProductCnt=0; //sysPara->para.totalProductCnt = sysPara->status.totalProductCnt; // No51版本改进 sysPara->status.lastProductCnt = sysPara->status.productCnt; ui.labelProductCnt->setText(QString::number(sysPara->status.productCnt)); // ui.labelTotalProductCnt->setText(QString::number( sysPara->para.totalProductCnt+sysPara->status.totalProductCnt)); // 20260410 总数栏改为预设数值栏 if (m_setNumDlg->getIsSet() && m_setNumDlg->getNum() > 0 && sysPara->status.productCnt == m_setNumDlg->getNum()) { LogInfo::setRunStatusText(QString("productCnt:%1 setNum:%2") .arg(sysPara->status.productCnt).arg(m_setNumDlg->getNum())); on_m_StopBtn_clicked(); } } void MainWidget::on_m_StartBtn_clicked() { if(sysPara){ test_flag = 0; if (!checkTriggerMode()) return; // 打印状态交给状态机修改 // sysPara->status.isPrinting=false; auto mgr = PrinterStateManager::instance(); #if !defined(FPGA_TEST) && !defined(QT_DEBUG) if (mgr && mgr->canStopPrint()) { mgr->requestTransition(PrinterEvent::StopPrint); } else {return;} #endif // SendPrintDataToFpga(0); // 0--正常打印,1--打印交替部分信息1; 2--打印交替部分信息2, /*-------------------------------------------------------------------*/ sysPara->status.lastSynColDelay = -1; //目的是为了清空原来的数据 /*---------------------------------开关回收槽------------------------------*/ setReclaimCloseBtnStatus(false); setReclaimOpenBtnStatus(false); updatePrintDisplayLabel(); // 20170717 移动此,以观察条形码打印异常问题。 if(!startPrintingFlag) { sysPara->devOp->printCtrl(PRINT_CTRL_START); printintFlag = true; } startPrintingFlag = true; // sysPara->status.isPrinting=true; if (mgr->canStartPrint() || mgr->isState(PrinterState::PRINTING)) { mgr->requestTransition(PrinterEvent::StartPrint); } // 高亮切换 changeHighLight(true); } } void MainWidget::on_m_StopBtn_clicked() { if(sysPara){ if (!sysPara->status.reclainTankReachEnd && !SIMULATE_PRINTING_MODE) { return; } // sysPara->status.isPrinting=false;// 打印状态交给状态机修改 auto mgr = PrinterStateManager::instance(); #if !defined(FPGA_TEST) && !defined(QT_DEBUG) if (mgr && mgr->canStopPrint()) { mgr->requestTransition(PrinterEvent::StopPrint); } else { return; } #endif sysPara->devOp->printCtrl2(1); sysPara->devOp->printCtrl( PRINT_CTRL_STOP);//:PRINT_CTRL_STOPSYNCNT setReclaimCloseBtnStatus(sysPara->status.currReclaimTankPos != 0); setReclaimOpenBtnStatus(sysPara->status.currReclaimTankPos == 0); printintFlag = false; startPrintingFlag = false; updatePrintDisplayLabel(); sysPara->status.waitHightVolOff = 1; sysPara->saveParaToFile(); // 将相关配置保存 if(sysPara->status.RandomBackCnt>5 && (sysPara->status.RandomNum>0)) { QMessageBox::StandardButton ret; ret = QMessageBox::warning(this, tr("提示"), tr("随机码文本将展出到U盘,请插入U盘"), QMessageBox::Ok | QMessageBox::Cancel); if (ret == QMessageBox::Ok){ sysPara->devOp->RandTxtBakup(0); //备份到U盘 } } // 高亮切换 changeHighLight(false); } } unsigned char blankDat1[BLANK_COL_NUM*MAX_PRINT_ROW_BYTE_NUM]={0}; void MainWidget::SendPrintDataToFpga(unsigned char alterEnable, bool isUpdate) { if(!sysPara) return ; // fileChange=false; Q_UNUSED(alterEnable); if(!isUpdate) { sysPara->devOp->writeFpgaPrintPara(1); sysPara->devOp->writeFpgaVariCtrlv2(); } sysPara->devOp->fpgaWr(0,blankDat1,sizeof(blankDat1));//...所加的空白偏移地址 unsigned char *dat; size_t sizeofdat; bool MaxCol4000; if(sysPara->status.flagOfNo67FPGA) MaxCol4000 = true; else MaxCol4000 = false; if(MaxCol4000){ dat =sysPara->status.printDat_Normal; sizeofdat = sizeof(sysPara->status.printDat_Normal); }else{ 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); static QElapsedTimer bnsTimer; static uint64_t nbRestartCount = 0; ++nbRestartCount; if(nbRestartCount >= 10) { auto elapsed = bnsTimer.restart(); qDebug() << (QString("SendPrintDataToFpga avg elapsed: %1 s").arg(elapsed / qreal(nbRestartCount) / 1000.0)); nbRestartCount = 0; } } int MainWidget::getCurrPrintStatus() { int printStatus; if (startPrintingFlag ) { if(printintFlag) { printStatus = 1; // 正在打印 } else { printStatus = 2; // 暂停喷印 } } else { printStatus = 3; // 停止打印 } return printStatus; } void MainWidget::setReclaimOpenBtnStatus(bool enable) { #ifdef __RFID_CARD if(sysPara->RFIDPara.inkCardTimeOut || sysPara->RFIDPara.solventCardTimeOut || sysPara->RFIDPara.needMaintenance) { enable = false; } #endif enable = !sysPara->status.airPushing && enable; ui.m_RightBtn->setEnabled(enable); } void MainWidget::setReclaimCloseBtnStatus(bool enable) { ui.m_LeftBtn->setEnabled(enable); } /** * @brief 翻转回收槽开启按钮的背景颜色 * 每次调用在 #BCBFC4 和 #FFD700 之间交替切换 */ void MainWidget::flashReclaimOpenBtn() { m_reclaimFlashState = !m_reclaimFlashState; ui.lb_RightBtn->setStyleSheet(m_reclaimFlashState ? "background-color:#FFD700;" : "background-color:#BCBFC4;"); } void MainWidget::stopFlashReclaimOpenBtn() { // 如果电机运行时间为0 就不暂停 if (sysPara == nullptr ||sysPara->status.curr_reclaimTankTime == 0 ||sysPara->status.currReclaimTankPos == 0) return; LogInfo::setRunStatusText("m_reclaimOpenBtnFlashTimer stop"); m_reclaimOpenBtnFlashTimer->stop(); m_reclaimFlashState = true; flashReclaimOpenBtn(); } void MainWidget::setReclaimStatus(bool isOpen, int rate) { if (isOpen) { if (!sysPara->status.airPushing) { QString str = rate == 100? tr("喷嘴已开启"):tr("喷嘴开启中"); ui.lb_RightBtn->setText(str); } ui.lb_LeftBtn->setText(tr("喷嘴关闭")); } else { QString str = rate == 0? tr("喷嘴已关闭"):tr("喷嘴关闭中"); ui.lb_LeftBtn->setText(str); if (!sysPara->status.airPushing) { ui.lb_RightBtn->setText(tr("喷嘴开启")); } } } static int mainInkPumpCtrlStatus = 0; static int mainInkPumpCtrlCnt = 0; //100ms 为单位 void MainWidget::airPushingProcess() { if(sysPara){ if (sysPara->status.airPushing) { QString labelTxt = tr("正在排气..."); setRunStatus(labelTxt); ui.lb_RightBtn->setText(labelTxt); setReclaimOpenBtnStatus(false); setReclaimCloseBtnStatus(false); //qDebug()<< "start airPushingProcess "<status.airPushingOnTime; // 执行排气 4 秒 sysPara->status.airPushingOnTime += 100; if(sysPara->para.airPushDurationSec <= 0 || sysPara->para.airPushDurationSec > 30) { sysPara->para.airPushDurationSec = 4; sysPara->saveParaToFile(); } // 延迟 半秒后才开回收槽,正式结束排气阶段 if(sysPara->status.airPushingOnTime >= sysPara->para.airPushDurationSec * 1000 + 500){ //qDebug()<< "start stop"; reclaimTanOpen(); sysPara->status.airPushingDone = 1; sysPara->status.airPushing = 0; sysPara->status.airPushingOnTime = 0; airPushTimer->stop(); setRunStatus(tr("喷嘴开启中")); return; } if(sysPara->status.airPushingOnTime >= sysPara->para.airPushDurationSec * 1000){ sysPara->devOp->controlViscosityPump(false); sysPara->devOp->controlCycleValve(false); if(!sysPara->devOp->isReclaimPumpOpen()) sysPara->devOp->controlReclaimPump(true, false); return; } } } } void MainWidget::reclaimTanOpen() { // 还原当前模式 if (sysPara->status.airPushing) { sysPara->status.isPumpValveControledByHand = sysPara->status.byHandStore; } sysPara->status.isPumpValveControledByHand = false; sysPara->devOp->mainInkCtrl(); sysPara->devOp->controlReclaimTankClose(false);//开回收槽之前先让关回收槽停止 MySleep(1000); sysPara->devOp->controlReclaimTankOpen(!sysPara->devOp->isReclaimTankOpenEnable()); sysPara->devOp->highVoltageCtrl(0); /*回收槽动作的时候务必关高压*/ // sysPara->status.reclaimTankstatus = 1; // setRunStatus(sysPara->devOp->isReclaimTankOpenEnable()?tr("正在打开回收槽..."):tr("停止打开")); setReclaimStatus(true, 0); if (!sysPara->para.reclaimTankTime) { // LogInfo::setRunStatusText(tr("警告!回收槽开关时间未设置!")); } else { } sysPara->status.currReclaimOperationCnt = 0; sysPara->status.reclainTankReachEnd = false; sysPara->status.reclainOpenAppending = true; sysPara->status.reclainCloseAppending = false; sysPara->status.reclaimBlockedCnt = 0; sysPara->status.canRunAirPushing = false; if (sysPara->status.reclainTankReachEnd) enablePrintButton(SIMULATE_PRINTING_MODE); } void MainWidget::initSheet() { // 仅当前按钮生效 QString startBtnSheet = R"( QPushButton { background-color: #1e8449; color: #99A89B; border-radius: 5px; } QPushButton:disabled { background-color: #bdc3c7; /* 灰色背景 */ color: #7f8c8d; /* 灰色文字 */ border: 1px solid #95a5a6; /* 灰色边框 */ } )"; ui.m_StartBtn->setStyleSheet(startBtnSheet); QString stopBtnSheet = R"( QPushButton { background-color: #D5614E; color: #99A89B; border-radius: 5px; } QPushButton:disabled { background-color: #bdc3c7; /* 灰色背景 */ color: #7f8c8d; /* 灰色文字 */ border: 1px solid #95a5a6; /* 灰色边框 */ } )"; ui.m_StopBtn->setStyleSheet(stopBtnSheet); const char* reclaimBtnNormalStyle = R"( QToolButton { padding: 16px 16px; border-radius: 6px; color: #333333; /* 深灰文字,与蓝色图标协调 */ /* 中性色背景,略带渐变制造立体感 */ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eefaff, stop: 1 #ceefff); border: 1px solid #a1a1a1; } QToolButton:hover { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #F5F7FA, stop: 1 #E8EBF0); border-color: #B0B6BE; } QToolButton:pressed { background-color: #D5D8DD; border-color: #A8AEB6; } QToolButton:disabled { color: #A0A5AB; background-color: #BCBFC4; border: 1px solid #BCBFC4; } )"; ui.m_RightBtn->setMinimumHeight(95); ui.m_LeftBtn->setMinimumHeight(95); ui.m_LeftBtn->setFixedHeight(95); ui.m_RightBtn->setFixedHeight(95); ui.m_RightBtn->setStyleSheet(reclaimBtnNormalStyle); ui.m_LeftBtn->setStyleSheet(reclaimBtnNormalStyle); // QString lbSheet = R"( // QLabel { // border: 1px solid #95a5a6; /* 灰色边框 */ // } // )"; // ui.lb_LeftBtn->setStyleSheet(lbSheet); // ui.lb_RightBtn->setStyleSheet(lbSheet); } void MainWidget::changeHighLight(bool isStart) { initSheet(); if (isStart) { QString highlightStyle = R"( QPushButton { background-color: #29B561; color: black; border-radius: 5px; border: 3px solid #f39c12; box-shadow: 0 0 8px rgba(231, 76, 60, 0.6); } QPushButton:disabled { background-color: #bdc3c7; /* 灰色背景 */ color: #7f8c8d; /* 灰色文字 */ border: 1px solid #95a5a6; /* 灰色边框 */ } )"; m_StartBtn->setStyleSheet(highlightStyle); } else { QString highlightStyle = R"( QPushButton { background-color: #e55f5f; color: black; border-radius: 5px; border: 3px solid #f39c12; box-shadow: 0 0 8px rgba(231, 76, 60, 0.6); } QPushButton:disabled { background-color: #bdc3c7; /* 灰色背景 */ color: #7f8c8d; /* 灰色文字 */ border: 1px solid #95a5a6; /* 灰色边框 */ } )"; m_StopBtn->setStyleSheet(highlightStyle); } } void MainWidget::on_m_RightBtn_clicked() { if(sysPara){ if (!sysPara->status.reclaimTankBlockedAppending) { if (sysPara->status.canRunAirPushing && (sysPara->status.currReclaimTankPos == 0)) { //2019/10/24 当回收槽未在顶的位置,不需要排气 // Pos == 0 回收槽关闭的情况下才可以执行排气; 先执行排气后开回收槽 if (!sysPara->status.airPushing) { //排气:打印、暂停打印置灰 enablePrintButton(false); sysPara->status.byHandStore = sysPara->status.isPumpValveControledByHand; sysPara->status.isPumpValveControledByHand = true; sysPara->devOp->mainInkCtrl(); sysPara->devOp->controlCycleValve(true); sysPara->devOp->controlViscosityPump(true);//关粘度泵 sysPara->devOp->controlMainInkPump(true);//主墨泵敞开 sysPara->devOp->mainInkCtrl(); sysPara->devOp->controlReclaimPump(true, false); // 回收泵开 sysPara->devOp->controlInkValve(true); //墨水阀 sysPara->devOp->controlInkValvePWM(true); //墨水阀 //qDebug()<< "start airpushings"; sysPara->status.airPushing = 1; sysPara->status.airPushingDone = 0; sysPara->status.airPushingOnTime = 0; airPushTimer->start(100); // 100ms } } else { reclaimTanOpen(); } } else if(sysPara->status.reclaimTankBlockedAppending) { sysPara->status.reclaimTankBlockedAppending = false; QMessageBox::StandardButton ret; ret = QMessageBox::warning(this, tr("警告"), tr("回收槽之前发生阻塞或回收槽时间设置错误,是否强制将当前位置设为到顶位置?"), QMessageBox::Ok | QMessageBox::Cancel); if (ret == QMessageBox::Ok){ sysPara->para.reclaimTankTime = sysPara->status.currReclaimTankPos/10; // onReclainTankPositionChanged(sysPara->para.reclaimTankTime * 10); } } // 喷嘴开启中 if (m_reclaimOpenBtnFlashTimer && !m_reclaimOpenBtnFlashTimer->isActive()){ ui.lb_RightBtn->setText(tr("正在排气...")); m_reclaimFlashState = true; m_reclaimOpenBtnFlashTimer->start(); LogInfo::setRunStatusText("m_reclaimOpenBtnFlashTimer start"); } } } void MainWidget::on_m_LeftBtn_clicked() { if(sysPara){ if(sysPara->status.reclaimTankBlockedAppending){ sysPara->status.reclaimTankBlockedAppending = false; QMessageBox::StandardButton ret; ret = QMessageBox::warning(this, tr("警告"), tr("回收槽之前发生阻塞或回收槽时间设置错误,是否强制将当前位置设为到顶位置?"), QMessageBox::Ok | QMessageBox::Cancel); if (ret == QMessageBox::Ok){ sysPara->status.currReclaimTankPos = 0; // onReclainTankPositionChanged(0); } } sysPara->devOp->controlReclaimTankClose(!sysPara->devOp->isReclaimTankCloseEnable()); enablePrintButton(SIMULATE_PRINTING_MODE); sysPara->devOp->highVoltageCtrl(0); // sysPara->status.reclaimTankstatus = 2; // setRunStatus(sysPara->devOp->isReclaimTankCloseEnable()?tr("正在关闭回收槽..."):tr("停止关闭")); setReclaimStatus(false, 100); if(!sysPara->para.reclaimTankTime){ // LogInfo::setRunStatusText(tr("警告!回收槽开关时间未设置!")); } sysPara->status.currReclaimOperationCnt = 0; sysPara->status.reclainTankReachEnd = false; sysPara->status.reclainOpenAppending = false; sysPara->status.reclainCloseAppending = true; sysPara->status.reclaimBlockedCnt = 0; enablePrintButton(false); stopFlashReclaimOpenBtn(); } } void MainWidget::on_m_ManageBtn_clicked() { #if defined(ARCH_X86) m_fileManageWidget->show(); #else m_fileManageWidget->showFullScreen(); #endif } void MainWidget::slt_setNum() { // 预设值 if(m_setNumDlg->getIsSet()) { unsigned int num = m_setNumDlg->getNum(); ui.labelTotalProductCnt->setText(QString::number(num)); ui.labelTotalProductCnt->show(); ui.lb_counter->show(); } else { ui.labelTotalProductCnt->hide(); ui.lb_counter->hide(); } } void MainWidget::slt_clearCnt() { if (sysPara) { sysPara->devOp->clearProductCnt(1);//当前产品计数器立即清零 ui.labelProductCnt->setText("0"); // SendPrintDataToFpga(0); } } void MainWidget::onReclaimOpenBtnFlashTimerTimeout() { flashReclaimOpenBtn(); } static int oldSizeFpga = -1; static int oldsizeSTM32 = -1; static int reclaimTankDelay = 0; void MainWidget::updateSysStatusToUI(){ //100ms if(sysPara){ RefreshStatusLight(); if(sysPara->status.lastProductCnt != sysPara->status.productCnt){ //产品计数 updateTotalCnt(0); } if(sysPara->status.ExpiryDispUpdate >0 ) { sysPara->status.ExpiryDispUpdate--; m_PrintDisplay->update();// 2018.5.25 } /*--------------------------------------------------------------------------*/ //if(sysPara->para.printTriggerMode == PRINT_TRIGGER_SYNCHRONIZER && printintFlag){ //同步器速度 if(( (sysPara->para.printTriggerMode == PRINT_TRIGGER_SYNCHRONIZER) ||(((sysPara->para.printTriggerMode == PRINT_TRIGGER_ELEC_EYE_VOLTATE_LEVEL) ||(sysPara->para.printTriggerMode == PRINT_TRIGGER_ELEC_EYE_EDGE) )&& sysPara->para.eleEyeTriggerSynPrintEn) ) )//&&printintFlag { if(sysPara->para.synPulseNumPerMm) { unsigned int tmp = ((unsigned int) sysPara->status.synPulseCntPer1s ) & 0xffffff; unsigned int mm = tmp /sysPara->para.synPulseNumPerMm * 60; // 1min总脉冲/毫米脉冲数 = 1min走过的距离mm数 int dotNum = sysPara->para.divideRatio?(FPGA_SYS_HZ/(sysPara->para.divideRatio*2)):0;// 1s时间内墨点数 (即晶振频率 64000) int colNum = sysPara->para.dotNumPerCol?dotNum/sysPara-> para.dotNumPerCol:0; // 第列可用墨点数 = 1s时间内墨点数/ 列需要墨点数 int pulseNum = colNum*sysPara->para.synNumPerCol/(1<<8); //synNumPerCol是被放大后的值 int maxMM = 0; if(!sysPara->para.charWidthSetEnable) { if( (sysPara->status.currPrintRow != 0) && (sysPara->para.printTriggerMode == PRINT_TRIGGER_SYNCHRONIZER) /*&& (sysPara->para.currPrintMode == FAST_PRINT || sysPara->para.currPrintMode == STANDARD_PRINT) */){ maxMM = calculateMaxSpeed(pulseNum); maxMM = maxMM *60; if(sysPara->para.alterPrint.enable) { maxMM = maxMM * 2; } } else { maxMM = (pulseNum/sysPara->para.synPulseNumPerMm) * 60;// 列的最大间距 // qDebug()<< "[Info] OLD COUNT mm" << maxMM; } } else { int pulsePS = getMaxSpeedCalcPara();//No67 maxMM = (pulsePS/sysPara->para.synPulseNumPerMm) * 60;// 列的最大间距 } // ui->labelSynRate->setText(tr("%1.%2[%3.%4]米/分").arg(mm/1000).arg(mm%1000,3,10,QLatin1Char('0')) // .arg(maxMM/1000).arg(maxMM%1000,3,10,QLatin1Char('0'))); // 20260414 0708:为防止变形,保存两位小数 ui.lb_curSpeed->setText(tr("%1.%2").arg(mm/1000).arg(mm%1000,2,10,QLatin1Char('0'))); ui.lb_maxSpeed->setText(tr("%1.%2").arg(maxMM/1000).arg(maxMM%1000,2,10,QLatin1Char('0'))); } else { ui.lb_curSpeed->setText("0"); ui.lb_maxSpeed->setText("0"); } // else // ui->labelSynRate->setText(""); sysPara->status.lastSynPulseCntPer1s = sysPara->status.synPulseCntPer1s; } else { ui.lb_curSpeed->setText("0"); ui.lb_maxSpeed->setText("0"); } // else // ui->labelSynRate->setText(""); /*--------------------------------------------------------------------------*/ if(sysPara->status.lastSynColDelay != sysPara->status.synColDelay){ // if(sysPara->para.printTriggerMode == PRINT_TRIGGER_SYNCHRONIZER) if((sysPara->para.printTriggerMode == PRINT_TRIGGER_SYNCHRONIZER) ||((sysPara->para.printTriggerMode == PRINT_TRIGGER_ELEC_EYE_VOLTATE_LEVEL ||sysPara->para.printTriggerMode == PRINT_TRIGGER_ELEC_EYE_EDGE) && sysPara->para.eleEyeTriggerSynPrintEn)) // ui->labelSynColDelay->setText(tr("列延时:%1点").arg(sysPara->status.synColDelay)); sysPara->status.lastSynColDelay = sysPara->status.synColDelay; } /*--------------------------------------------------------------------------*/ static int i=0; i++; if(sysPara->status.stm32Verion == 0){ if(i % 10 == 0){ sysPara->devOp->readSTM32Version(); } } if(sysPara->status.stm32Time == 0){ if(i % 10 == 0){ sysPara->devOp->readSTM32Time(); } } if(sysPara->status.fpgaVersionNum == 0){ //因为进入系统就会进主界面,马上就会将版本号读出 if(i % 10 == 0){ sysPara->devOp->readFpgaVersionNum(); sysPara->devOp->readbuilDat(); } // ui->labelFpgaVersionNum->setText(QString("%1/F%2.%3.%4").arg(SOFTWARE_VER_NUM).arg(0).arg(0).arg(0) ); } else{ static bool logflag5 = true; unsigned int num = sysPara->status.fpgaVersionNum & 0xf000; if(num != 0x1000 && num != 0x6000 && num != 0x2000 && num != 0x8000 && logflag5){ //未读取到版本号 sysPara->status.fpgaVersionNum = 0; } else if(logflag5){ // emit readFPGAVersionReady(); logflag5 = false; sysPara->devOp->writeFpgaPrintPara(true); QString ARM_Version; ARM_Version.sprintf("%d.%d.%02d%s%s", UP_PRINTER_MAJOR_VER, UP_PRINTER_MINOR_VER,UP_PRINTER_RIVISION_VER,SUB_VERSION,SUB_RFID); // ui->labelFpgaVersionNum->setText(QString("A%1/F%2.%3.%4").arg(ARM_Version).arg(sysPara->status.fpgaVersionNum >> 12) // .arg((sysPara->status.fpgaVersionNum>>8) & 0x0f).arg(sysPara->status.fpgaVersionNum&0xff) ); QString versionStr = QString("A%1/F%2.%3.%4").arg(ARM_Version).arg(sysPara->status.fpgaVersionNum >> 12) .arg((sysPara->status.fpgaVersionNum>>8) & 0x0f).arg(sysPara->status.fpgaVersionNum&0xff); emit showVserionInfo(versionStr); } } static bool logflag6 = false; if(!logflag6){ if(sysPara->status.fpgaVersionNum !=0 && sysPara->status.stm32Verion != 0){ UpdateUIVersion(); logflag6 = true; } } bool found_CNT1 = false; bool found_CNT2 = false; bool found_CNT3 = false; bool found_CNT4 = false; /*--------------------------------------------------------------------------*/ // if(sysPara->status.variNum && (ui->stackedWidgetText->currentWidget() == ui->pagePrintTextDisplay)){ if(sysPara->status.variNum){ bool updatePrintTextDisplayFlag = false; for(int i = 0; i < sysPara->status.variNum; i++){ int val = 0; switch( Public::getType(sysPara->status.vars[i].type)) { case CALANDAR_YEAR:val = sysPara->status.calandar_and_dat.year;break; case CALANDAR_MONTH:val = sysPara->status.calandar_and_dat.month;break; case CALANDAR_DAY:val = sysPara->status.calandar_and_dat.day;break; case CALANDAR_WEEK:val = sysPara->status.calandar_and_dat.week;break; case CALANDAR_HOUR:val = sysPara->status.calandar_and_dat.hour;break; case CALANDAR_MINUTE:val = sysPara->status.calandar_and_dat.minute;break; case CALANDAR_SECOND:val = sysPara->status.calandar_and_dat.second;break; case CALANDAR_CNT1:val = QString::number(sysPara->status.calandar_and_dat.cnt1CurrValue,16).toInt();found_CNT1=true;break; case CALANDAR_CNT2:val = QString::number(sysPara->status.calandar_and_dat.cnt2CurrValue,16).toInt();found_CNT2=true;break; case CALANDAR_CNT3:val = QString::number(sysPara->status.Status_Counter3.cnt3CurrValue,16).toInt();found_CNT3=true;break; case CALANDAR_CNT4:val = QString::number(sysPara->para.cnt4CurrValue,10).toInt();found_CNT4=true;break; case RANDOMNUM : val = QString::number( sysPara->status.calandar_and_dat.RandomValue1, 16).toInt(); break; case CALANDAR_XDAY:val = sysPara->status.XXXDay;break; case EXPIRYDATE: break; default:qDebug() << "error,unknown variable type:" << sysPara->status.vars[i].type; } if(sysPara->status.vars[i].currVal != val) //{ updatePrintTextDisplayFlag = true; sysPara->status.vars[i].currVal = val; //} } if(updatePrintTextDisplayFlag) //减少不必要的刷新动作 { m_PrintDisplay->updateSysStatusToUI(); } } // emit setCNT1Select(found_CNT1); // emit setCNT2Select(found_CNT2); // emit setCNT3Select(found_CNT3); if(sysPara->para.isEnableGetDataButton) { // ui->pushButtonGetData->setEnabled(true); } else { // ui->pushButtonGetData->setEnabled(false); } if(TEST_MODE) enablePrintButton(true); // ui->label_size->setText(tr("%1/%2/%3").arg(sysPara->status.sizeFPGA).arg(sysPara->status.sizequeueFPGA).arg(sysPara->status.sizeSTM32)); if(oldSizeFpga != sysPara->status.sizeFPGA){ oldSizeFpga = sysPara->status.sizeFPGA; } if(oldsizeSTM32 != sysPara->status.sizeSTM32){ oldsizeSTM32 = sysPara->status.sizeSTM32; } /*if(sysPara->status.reclaimTankstatus == 6){ sysPara->status.flagOfRebootEnable = true; reclaimTankDelay = 0; } if(sysPara->status.flagOfRebootEnable && sysPara->status.reclaimTankstatus != 0 && sysPara->status.reclaimTankstatus != 6 && sysPara->status.reclaimTankstatus != 3){ sysPara->status.flagOfRebootEnable = false; }*/ if(sysPara->status.currReclaimTankPos <= 5) sysPara->status.flagOfRebootEnable = true; else sysPara->status.flagOfRebootEnable = false; if(sysPara->status.flagOfRebootEnable || TEST_MODE){ // ui->pushButton_Reboot->setEnabled(true); }else{ // ui->pushButton_Reboot->setEnabled(false); } } } bool MainWidget::checkRed(AlarmStatus &status) { if (status.highVoltageFault == DEV_STATUS_RED) { m_stateStr = tr("高压故障"); return true; } if (status.chargeFault == DEV_STATUS_RED) { m_stateStr = tr("相位故障"); return true; } if (status.viscosityWarn == DEV_STATUS_RED) { m_stateStr = tr("粘度故障"); return true; } if (status.recycleWarn == DEV_STATUS_RED) { m_stateStr = tr("回收故障"); return true; } if (status.solveLevelWarn == DEV_STATUS_RED) { m_stateStr = tr("溶液液位"); return true; } if (status.inkWaterLevel == DEV_STATUS_RED) { m_stateStr = tr("墨水液位"); return true; } if (status.inkLeak == DEV_STATUS_RED) { m_stateStr = tr("墨水缸满"); return true; } if (status.inkSwint == DEV_STATUS_RED) { m_stateStr = tr("墨线开关"); return true; } return false; } bool MainWidget::checkYellow(AlarmStatus &status) { if (status.highVoltageFault == DEV_STATUS_YELLOW) { m_stateStr = tr("高压故障"); return true; } if (status.chargeFault == DEV_STATUS_YELLOW) { m_stateStr = tr("相位故障"); return true; } if (status.viscosityWarn == DEV_STATUS_YELLOW) { m_stateStr = tr("粘度故障"); return true; } if (status.recycleWarn == DEV_STATUS_YELLOW) { m_stateStr = tr("回收故障"); return true; } if (status.solveLevelWarn == DEV_STATUS_YELLOW) { m_stateStr = tr("溶液液位"); return true; } if (status.inkWaterLevel == DEV_STATUS_YELLOW) { m_stateStr = tr("墨水液位"); return true; } if (status.inkLeak == DEV_STATUS_YELLOW) { m_stateStr = tr("墨水缸满"); return true; } if (status.inkSwint == DEV_STATUS_YELLOW) { m_stateStr = tr("墨线开关"); return true; } return false; } void MainWidget::updateGeneralState(AlarmStatus status) { // 有红则红,全绿则绿,红>黄>绿 // 检查从后往前判断,因为取最后一个状态QString bool isRed = checkRed(status); if (isRed) { m_stateColor = DEV_STATUS_RED; } else { bool isYellow = checkYellow(status); if (isYellow) { m_stateColor = DEV_STATUS_YELLOW; } else { m_stateColor = DEV_STATUS_GREEN; m_stateStr= tr("正常"); } } // 自检时设为正常, 关机设为正常 if (!sysPara->status.selfCheckDone || sysPara->status.powerOffAppending) { m_stateColor = DEV_STATUS_GREEN; m_stateStr= tr("正常"); } if (m_stateColor == DEV_STATUS_GREEN) { ui.fra_state->setStyleSheet("background-color: #ccffcc;"); } else if (m_stateColor == DEV_STATUS_RED) { ui.fra_state->setStyleSheet("background-color: #ff6b6b;"); } else { ui.fra_state->setStyleSheet("background-color: #ffd93c;"); } ui.lb_generalState->setText(m_stateStr); } int MainWidget::calculateMaxSpeed(int backup) { float stroke; int valid_array; int rongdian = 0; int mm; int oscfreq = 0; // QSizeF size = ui->textEdit->document()->size(); switch (sysPara->para.oscillatoFreq) { case CRYS_64K: oscfreq = 64000; break; case CRYS_83K: oscfreq = 83000; break; case CRYS_96K: oscfreq = 96000; break; case CRYS_128K: oscfreq = 128000; break; default: break; } stroke = sysPara->para.printColDelay/sysPara->para.synPulseNumPerMm; rongdian = sysPara->status.currPrintRow * (float)sysPara->para.reducedPixelNumRatio/100; valid_array = sysPara->status.currPrintRow - rongdian; switch (sysPara->para.currPrintMode) { case FAST_PRINT: mm = (float)(stroke * oscfreq /(sysPara->status.currPrintRow +1)); break; case STANDARD_PRINT: mm = (float)( (stroke * oscfreq) / (valid_array * 2)); break; case SLOW_PRINT_ONE: mm = (float)( (stroke * oscfreq) / (valid_array * 3)); break; case SLOW_PRINT_TWO: mm = (float)( (stroke * oscfreq) / (valid_array * 4)); break; case SLOW_PRINT_THR: mm = (float)( (stroke * oscfreq) / (valid_array * 5)); break; case SLOW_PRINT_FOR: mm = (float)( (stroke * oscfreq) / (valid_array * 6)); break; case SLOW_PRINT_FIV: mm = (float)( (stroke * oscfreq) / (valid_array * 7)); break; case SLOW_PRINT_SIX: mm = (float)( (stroke * oscfreq) / (valid_array * 8)); break; case SLOW_PRINT_SEV: mm = (float)( (stroke * oscfreq) / (valid_array * 9)); break; case SLOW_PRINT_EIG: mm = (float)( (stroke * oscfreq) / (valid_array * 10)); break; case SLOW_PRINT_NIE: mm = (float)( (stroke * oscfreq) / (valid_array * 11)); break; default: mm = backup/sysPara->para.synPulseNumPerMm; break; } return mm; } int MainWidget::getMaxSpeedCalcPara(){ sysPara->para.printRowDelay = sysPara->para.currPrintMode; if(sysPara->status.isPrinting == false) sysPara->status.pixNumPerCol = sysPara->status.currPrintRow; else sysPara->status.currPrintRow = sysPara->status.pixNumPerCol; sysPara->para.pixNumPerCol = sysPara->status.pixNumPerCol; sysPara->para.reducedPixelNum = sysPara->para.reducedPixelNumRatio*sysPara->para.pixNumPerCol/100; int dotNumPerCol = (sysPara->para.pixNumPerCol- sysPara->para.lineEndAdjustPointCnt)*(sysPara->para.printRowDelay + 1) + (sysPara->para.lineEndAdjustPointCnt)*(sysPara->para.lineEndAdjustPointDelay + 1); dotNumPerCol = sysPara->para.pixNumPerCol? ((dotNumPerCol*(sysPara->para.pixNumPerCol - sysPara->para.reducedPixelNum))/sysPara->para.pixNumPerCol):1; // sysPara->para.dotNumPerCol += sysPara->para.printColDelay; dotNumPerCol =( sysPara->para.alterPrint.enable)? dotNumPerCol/2:dotNumPerCol; int dotNum = sysPara->para.divideRatio?(FPGA_SYS_HZ/(sysPara->para.divideRatio*2)):0;// 1s时间内墨点数 (即晶振频率 64000) int colNum = dotNumPerCol?dotNum/dotNumPerCol:0; // 第列可用墨点数 = 1s时间内墨点数/ 列需要墨点数 int pulseNum = colNum*sysPara->para.synNumPerCol/(1<<8); //synNumPerCol是被放大后的值 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) { return; } pPicScene->clearSelection(); pPicScene->update(); 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); int coldot = qMin(int(contentRect.right()), MaxCol4000 ? MAX_PRINT_COL_NUM_Normal : MAX_PRINT_COL_NUM_Wide); QSize size(coldot, sysPara->para.canvasHeight); if(size.isEmpty()) { //场景为空时,渲染空场景并刷新界面 handleEmptySize(); return; } QImage image(size, QImage::Format_ARGB32); image.fill(0x00ffffff);//填充白色 QPainter painter(&image); int firstRow = 0; int myvariNum=0; int expiryVarNum = 0; 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; qDebug() << "Loading scene items: \r\n\r\n\r\n"; QList items = pPicScene->items(); foreach (QGraphicsItem *item, items) { PicTextItem *picText = qgraphicsitem_cast(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(); } const QRectF itemSceneRect = item->sceneBoundingRect(); const QRectF clippedSceneRect = itemSceneRect.intersected(contentRect); if(clippedSceneRect.isEmpty()) continue; // const QRect itemRect = clippedSceneRect.translated(-contentRect.topLeft()).toAlignedRect(); // 直接使用场景绝对坐标,不进行平移 const QRect itemRect = clippedSceneRect.toAlignedRect(); const QRectF sourceRect = clippedSceneRect; if(picText && picText->sourceType() == SourceType::COUNTER) { PicCounterItem* counterItem = qgraphicsitem_cast(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() + 2; varPara.startRowPos = itemRect.top(); varPara.currVal = 0; varPara.bold = 0; varPara.letterSpace = counterItem->letterSpace(); ++sysPara->status.variNum; } pPicScene->render(&painter, itemRect, sourceRect); } sysPara->status.currPrintRow = size.height(); sysPara->status.currPrintCol = size.width(); imageToPrintData(image, 0, 0); generateCharRamDataV2(); /*-------------------------------切换到显示窗口-----------------------------------*/ qDebug() << "currPrintCol: " << sysPara->status.currPrintCol; LogInfo::setRunStatusText("currPrintCol: " + QString::number(sysPara->status.currPrintCol)); LogInfo::setRunStatusText("currPrintRow: " + QString::number(sysPara->status.currPrintRow)); // 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() { // 初始化空场景的尺寸(默认适配打印最大尺寸,避免界面空白) bool MaxCol4000 = sysPara->status.flagOfNo67FPGA ? true : false; QSize emptySize(MaxCol4000 ? MAX_PRINT_COL_NUM_Normal : MAX_PRINT_COL_NUM_Wide, MAX_PRINT_ROW_NUM); // 初始化打印参数,避免空场景导致的参数异常 sysPara->status.currPrintRow = 0; sysPara->status.currPrintCol = 0; // emptySize.width(); sysPara->status.variNum = 0; sysPara->status.QRvariNum = 0; sysPara->status.ExpiryVarNum = 0; sysPara->status.CurrDateVariNum = 0; sysPara->status.classVariNum = 0; // 清空打印数据缓冲区 unsigned char *dat = MaxCol4000 ? sysPara->status.printDat_Normal : sysPara->status.printDat; memset(dat, 0, MaxCol4000 ? sizeof(sysPara->status.printDat_Normal) : sizeof(sysPara->status.printDat)); // 刷新预览显示,显示空场景(白色背景) auto rows = sysPara->para.AlterMode?sysPara->status.currAlterPrintRow : sysPara->status.currPrintRow; 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(); return; } void MainWidget::updatePrintDisplayLabel() { m_PrintDisplay->update(); } void MainWidget::RefreshStatusLight(){//100ms if(sysPara){ static int hdint = 0; static int reclainTankReachEnd = 0; if((!(sysPara->status.statWarn & WARN_STATUS_HDINT)) && (hdint == 0)) { //喷头盖由开变关 // 检查回收槽是否到底,到底才能打印 if (sysPara->status.reclainTankReachEnd) { // sysPara->devOp->highVoltageCtrl(sysPara->para.HighVoltageAmplitude); enablePrintButton(true); } else { enablePrintButton(false); } } hdint = !(sysPara->status.statWarn & WARN_STATUS_HDINT); if(sysPara->status.reclainTankReachEnd && reclainTankReachEnd == 0) { //开回收槽到底 if (!(sysPara->status.statWarn & WARN_STATUS_HDINT)) { //喷头盖是关闭的状态 // sysPara->devOp->highVoltageCtrl(sysPara->para.HighVoltageAmplitude); } } reclainTankReachEnd = sysPara->status.reclainTankReachEnd; if(sysPara->status.lastStatWarn != sysPara->status.statWarn || flagOfClearHighVltageWarnning){ if(!(sysPara->status.statWarn & WARN_STATUS_INK_SWINT)){//墨线开关 // ui->labelStatusInkSwint->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); alarmStatus.inkSwint = DEV_STATUS_GREEN; } else { // ui->labelStatusInkSwint->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMRed.PNG"))); alarmStatus.inkSwint = DEV_STATUS_RED; } if(!(sysPara->status.statWarn & WARN_STATUS_SUMP_WARN)){ //液位渗漏,高电平警告 // ui->labelStatusInkLeak->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); alarmStatus.inkLeak = DEV_STATUS_GREEN; } else { // ui->labelStatusInkLeak->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMRed.PNG"))); alarmStatus.inkLeak = DEV_STATUS_RED; strTitle = tr("墨水缸满报警"); if(sysPara->devOp->isMixValveOpen()) { sysPara->devOp->controlMixValve(false); //关掉混合阀 } } if(!(sysPara->status.statWarn & WARN_STATUS_INK_WARN)){ // ui->labelStatusInkWaterLevel->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); alarmStatus.inkWaterLevel = DEV_STATUS_GREEN; } else { // ui->labelStatusInkWaterLevel->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMRed.PNG"))); alarmStatus.inkWaterLevel = DEV_STATUS_RED; strTitle = tr("墨水液位报警"); } if(!(sysPara->status.statWarn & WARN_STATUS_SOLV_WARN)){ // ui->labelStatusSolvLevelWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); alarmStatus.solveLevelWarn = DEV_STATUS_GREEN; } else { // ui->labelStatusSolvLevelWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMRed.PNG"))); alarmStatus.solveLevelWarn = DEV_STATUS_RED; strTitle = tr("溶剂液位报警"); } if(!(sysPara->status.statWarn & WARN_STATUS_RECYCLE_FAULT) ){ // ui->labelStatusRecycleWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); alarmStatus.recycleWarn = DEV_STATUS_GREEN; } else { // ui->labelStatusRecycleWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMRed.PNG"))); alarmStatus.recycleWarn = DEV_STATUS_RED; } //static int HVfaultCnt=0; if(!(sysPara->status.statWarn & WARN_STATUS_POWER_MON)){ if(!sysPara->status.lastHighVoltageFault) { flagOfClearHighVltageWarnning = false; // ui->labelStatusHighVoltageFault->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); alarmStatus.highVoltageFault = DEV_STATUS_GREEN; } // HVfaultCnt=0; //sysPara->status.HVFaultCloseEn=0; } else { // ui->labelStatusHighVoltageFault->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMRed.PNG"))); alarmStatus.highVoltageFault = DEV_STATUS_RED; if(startPrintingFlag && printintFlag){ //已经在打印,则暂停打印 2013-9-15高压报警停止充电 // on_pushButtonPausePrint_pressed(); on_m_StopBtn_clicked(); LogInfo::setRunStatusText(tr("高压故障,暂停打印")); setRunStatus(tr("高压故障,暂停打印")); strTitle = tr("高压故障,暂停打印."); sysPara->status.lastHighVoltageFault = true; } if((sysPara->status.currReclaimTankPos != 0) && sysPara->para.HVFaultCloseEn ) { //HVfaultCnt++; // 高压故障关回收槽 if(sysPara->status.HVFaultCloseEn==0){ sysPara->status.reclaimTankBlockedAppending=0; sysPara->status.reclaimCloseCnt=100; // on_pushButtonReclaimTankClose_pressed(); on_m_LeftBtn_clicked(); sysPara->status.reclaimTankBlockedAppending=1; LogInfo::setRunStatusText(tr("高压故障,关回收槽")); setRunStatus(tr("高压故障,关回收槽和墨线")); } sysPara->status.HVFaultCloseEn=1; } } } /*-----------------------------------------------------------------------------------*/ sysPara->status.lastStatWarn = sysPara->status.statWarn; if(sysPara->status.lastViscosityFault != sysPara->status.viscosityFault){ if(sysPara->status.viscosityFault==0){ // ui->labelStatusViscosityWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); alarmStatus.viscosityWarn = DEV_STATUS_GREEN; } else { if(sysPara->status.viscosityFault==1){ // ui->labelStatusViscosityWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMRed.PNG"))); alarmStatus.viscosityWarn = DEV_STATUS_RED; } else if(sysPara->status.viscosityFault==2) { // ui->labelStatusViscosityWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMYellow.PNG"))); alarmStatus.viscosityWarn = DEV_STATUS_YELLOW; } } } sysPara->status.lastViscosityFault = sysPara->status.viscosityFault; /*-----------------------------------------------------------------------------------*/ if(!(sysPara->status.statWarn & WARN_STATUS_RECYCLE_FAULT)){ //20140211 nie if(sysPara->status.RecycleWarnCnt) alarmStatus.recycleWarn = DEV_STATUS_GREEN; // ui->labelStatusRecycleWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); sysPara->status.RecycleWarnCnt = 0; sysPara->status.lastRecycleWarn = 0; } else { if(!sysPara->status.lastRecycleWarn && !sysPara->status.isPumpValveControledByHand && sysPara->status.selfCheckDone) { if(sysPara->status.RecycleWarnCnt > RECYCLE_WARN_DELAY) { sysPara->status.lastRecycleWarn = RECYCLE_WARN_DELAY;//5s alarmStatus.recycleWarn = DEV_STATUS_RED; // ui->labelStatusRecycleWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMRed.PNG"))); sysPara->status.reclaimCloseCnt=100; if(sysPara->para.RecycleWarnAction) { if((sysPara->status.currReclaimTankPos != 0) && !sysPara->devOp->isReclaimTankCloseEnable()){ on_m_StopBtn_clicked(); on_m_LeftBtn_clicked(); if (m_warn) { LogInfo::setRunStatusText(tr("回收故障,关闭回收槽,关墨线")); setRunStatus(tr("回收故障,关闭回收槽,关墨线"),true,true); } } } else if (m_warn) {setRunStatus(tr("回收故障."),true,true); } } else { sysPara->status.RecycleWarnCnt ++ ; alarmStatus.recycleWarn = DEV_STATUS_YELLOW; // ui->labelStatusRecycleWarn->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMYellow.PNG"))); if(sysPara->status.RecycleWarnCnt%10==9) LogInfo::setRunStatusText(tr("回收异常,墨线可能偏离.(%1)").arg(sysPara->status.RecycleWarnCnt)); } } else if(sysPara->status.lastRecycleWarn)sysPara->status.lastRecycleWarn--; } // if(startPrintingFlag ){ // if(printintFlag) // setRunStatus(tr("正在喷印...")); // else // setRunStatus(tr("暂停喷印...")); // } if(sysPara->status.isPrinting && sysPara->status.selfCheckDone){ setRunStatus(tr("正在喷印.......")); setReclaimCloseBtnStatus(false); setReclaimOpenBtnStatus(false); } // 20160620 新增主界面显示:压力,粘度,隔膜位置,晶振电压数,相位 alarmStatus.pressValue = QString("%1/%2").arg(sysPara->status.PRESSURE).arg(sysPara->para.pressure); alarmStatus.visoValue = QString("%1/%2").arg(sysPara->status.viscosity).arg(sysPara->para.viscosity); if(sysPara->para.gearPumpEnable) { alarmStatus.gearPumpRunSpeed = QString("%1").arg(sysPara->status.gearPumpRunSpeed); } alarmStatus.highVol = QString::number(sysPara->status.HV_DETOUT) + "/" + QString::number(sysPara->para.maxHighVoltageDAC); alarmStatus.dataSize = QString("%1/%2/%3").arg(sysPara->status.sizeFPGA).arg(sysPara->status.sizequeueFPGA).arg(sysPara->status.sizeSTM32); } } bool MainWidget::updatePhaseIndicatorLight(){ if(sysPara==0) return 0; /*------------------------------------------喷头盖未关或回收槽未全部打开的时候不报相位故障-------------------------------------------------*/ if((!sysPara->status.flight_tm_error && !sysPara->status.detect_phase_error) || (sysPara->status.statWarn & WARN_STATUS_HDINT) || !sysPara->status.reclainTankReachEnd){ //故障后必须等手动按故障恢复才会继续 if(!sysPara->para.suspendAfterPhaseFault && !sysPara->para.powerOffAfterPhaseFault){ if(sysPara->status.lastPhaseFault){ sysPara->status.lastPhaseFault = 0; // ui->labelStatusChargefault->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); alarmStatus.chargeFault = DEV_STATUS_GREEN; } } sysPara->status.phaseErrorCnt = 0; } else { if(sysPara->status.phaseErrorCnt < 10) sysPara->status.phaseErrorCnt ++ ; else { if(!sysPara->status.lastPhaseFault){ alarmStatus.chargeFault = DEV_STATUS_RED; sysPara->status.lastPhaseFault = 1; if(sysPara->status.flight_tm_error) { LogInfo::setRunStatusText(tr("相位故障:飞行时间错误!")); } if(sysPara->status.detect_phase_error) { LogInfo::setRunStatusText(tr("相位故障:相位检测错误!")); } } if(sysPara->para.powerOffAfterPhaseFault ){ if(!sysPara->status.powerOffAfterPhaseFaultAppending){ sysPara->status.powerOffAfterPhaseFaultAppending = 1; _on_pushButtonPowerOff_pressed(false); LogInfo::setRunStatusText(tr("相位故障,准备关机")); setRunStatus(tr("相位故障,准备关机")); strTitle = tr("相位故障,准备关机"); } } else if(sysPara->para.suspendAfterPhaseFault){ if(sysPara->status.isPrinting){ //已经在打印,则暂停打印 on_m_StopBtn_clicked(); LogInfo::setRunStatusText(tr("相位故障,暂停打印")); setRunStatus(tr("相位故障,暂停打印")); strTitle = tr("相位故障,暂停打印"); } else if(!sysPara->status.DACDisable){ sysPara->devOp->printCtrl(PRINT_CTRL_DAC_DISABLE); sysPara->status.DACDisable = true; LogInfo::setRunStatusText(tr("相位故障,屏蔽DAC输出")); setRunStatus(tr("相位故障,屏蔽充电")); strTitle = tr("相位故障,屏蔽充电"); } } if(sysPara->para.closeReclaimTankWhenPhaseFault) { on_m_LeftBtn_clicked(); LogInfo::setRunStatusText(tr("相位故障, 关闭回收槽")); setRunStatus(tr("相位故障,关闭回收槽")); strTitle = tr("相位故障,关闭回收槽"); } } } return sysPara->status.lastPhaseFault; } //void MainWidget::mouseDoubleClickEvent(QMouseEvent *event) //{ // if (event->button() != Qt::LeftButton) { // QWidget::mouseDoubleClickEvent(event); // return; // } // QPoint globalPos = event->globalPos(); // const int expandSize = 50; // 扩大到50像素 // // 检测函数 // auto isInExpandedRect = [&](QWidget* widget) -> bool { // if (!widget) return false; // QRect rect = widget->geometry(); // rect.translate(widget->parentWidget()->mapToGlobal(QPoint(0, 0))); // rect.adjust(-expandSize, -expandSize, expandSize, expandSize); // return rect.contains(globalPos); // }; // if (isInExpandedRect(ui.sub3)) { // if (m_setNumDlg) { // m_setNumDlg->show(); // event->accept(); // return; // } // } // if (isInExpandedRect(ui.fra_state)) { // LogInfoCtrl::instance()->emitSigShow(); // event->accept(); // return; // } // QWidget::mouseDoubleClickEvent(event); //} void MainWidget::mousePressEvent(QMouseEvent *event) { if (event->button() != Qt::LeftButton) { QWidget::mousePressEvent(event); return; } QPoint currentPos = event->globalPos(); qint64 currentTime = QDateTime::currentMSecsSinceEpoch(); // 计算时间和距离 qint64 timeDiff = currentTime - m_lastClickTime; int distance = QLineF(m_lastClickPos, currentPos).length(); // 判断是否为双击(使用自定义阈值) if (timeDiff <= m_doubleClickInterval && distance <= m_doubleClickDistance) { // 触发双击逻辑 handleDoubleClick(event); m_lastClickTime = 0; // 重置,防止三连击触发多次 m_lastClickPos = QPoint(); event->accept(); return; } // 更新最后一次点击信息 m_lastClickPos = currentPos; m_lastClickTime = currentTime; QWidget::mousePressEvent(event); } void MainWidget::handleDoubleClick(QMouseEvent *event) { QPoint globalPos = event->globalPos(); // 检查目标区域 if (isInExpandedRect(ui.sub3, globalPos, m_doubleClickDistance)) { if (m_setNumDlg) { m_setNumDlg->show(); } return; } if (isInExpandedRect(ui.fra_state, globalPos, m_doubleClickDistance)) { LogInfoCtrl::instance()->emitSigShow(); return; } } bool MainWidget::isInExpandedRect(QWidget* widget, const QPoint& globalPos, int expandSize) { if (!widget || !widget->isVisible()) return false; QRect rect = widget->geometry(); rect.translate(widget->parentWidget()->mapToGlobal(QPoint(0, 0))); rect.adjust(-expandSize, -expandSize, expandSize, expandSize); return rect.contains(globalPos); } bool MainWidget::checkTriggerMode() { /******2020/2/29*****/ if(sysPara->para.printTriggerMode == PRINT_TRIGGER_SYNCHRONIZER) //同步模式下,判断喷印间隔是否设置合理 { QSizeF size = QSizeF(sysPara->status.currPrintCol, sysPara->status.currPrintRow); float stroke,print_len_min; stroke = sysPara->para.printColDelay/sysPara->para.synPulseNumPerMm; print_len_min = stroke * size.width(); if(print_len_min > sysPara->para.synTriggerPrintLenMm && !sysPara->para.charWidthSetEnable) { QMessageBox::information(this,tr("错误"),tr("喷印间隔过短,应高于%1!").arg(print_len_min)); return false; } } /******2020/2/29 end*****/ #ifndef QT_DEBUG if(!SIMULATE_PRINTING_MODE){ if (!sysPara->status.reclainTankReachEnd) { return; } if((sysPara->status.statWarn & WARN_STATUS_HDINT)){ QMessageBox::information(this,tr("错误"),tr("喷头盖未关,请先关喷头盖!")); return ; } if((sysPara->status.statWarn & WARN_STATUS_INK_SWINT)){ QMessageBox::information(this,tr("错误"),tr("墨线未开,请先开墨线开关!")); return ; } } #endif bool MaxCol4000; if(sysPara->status.flagOfNo67FPGA) MaxCol4000 = true; else MaxCol4000 = false; if(sysPara->status.currPrintCol > (MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide)){ QMessageBox::critical(0,tr("错误"),tr("当前总列数 %1 ,支持的总列数为 %2,请减少打印串的长度").arg(sysPara->status.currPrintCol).arg((MaxCol4000?MAX_PRINT_COL_NUM_Normal:MAX_PRINT_COL_NUM_Wide))); return false; } if(!((sysPara->para.printTriggerMode == PRINT_TRIGGER_SYNCHRONIZER) ||((sysPara->para.printTriggerMode == PRINT_TRIGGER_ELEC_EYE_VOLTATE_LEVEL ||sysPara->para.printTriggerMode == PRINT_TRIGGER_ELEC_EYE_EDGE) && sysPara->para.eleEyeTriggerSynPrintEn)) ) { int dotNumPerCol = sysPara->status.currPrintRow*(1 + sysPara->para.printRowDelay) + sysPara->para.printColDelay; long printTmUs = 1.0f*dotNumPerCol*(1 + sysPara->para.charBold)*sysPara->status.currPrintCol*(2*sysPara->para.divideRatio)/(FPGA_SYS_HZ/1000000); if((printTmUs/1000 + 3) > (sysPara->para.printDelayMs)\ && (sysPara->para.timeTriggerPrintMode == TIME_TRIGGER_PRINT_MODE_HEAD_TO_HEAD) && (sysPara->para.printTriggerMode == PRINT_TRIGGER_TIME ) ) // 在电眼方式下,是否需要判呢? { QMessageBox::critical(0,tr("错误"),tr("打印耗时 %1ms ,触发间隔 :%2ms ,触发间隔至少应当大于打印耗时3ms").arg(printTmUs/1000).arg(sysPara->para.printDelayMs)); return false; } } return true; } void MainWidget::onLabelFaultRusumePressed(){ if(sysPara){ sysPara->status.flagOfSpeedAlarm = false; sysPara->status.mainInkPumpError = false; sysPara->status.mainInkPumpRunTmCnt = 0; sysPara->status.compressPumpError = false; sysPara->status.compressPumpRunTmCnt = 0; sysPara->devOp->resumeFault(); ui.lb_nozzleState->clear(); sysPara->status.beeperOnFlag = false; sysPara->devOp->controlBeeper(false); sysPara->status.heaterONTimeCnt = 0; //加热块计数清零 // ui->labelStatusChargefault->setPixmap(QPixmap(QString::fromUtf8(":/image/ALARMGreen.PNG"))); alarmStatus.chargeFault = DEV_STATUS_GREEN; sysPara->status.DACDisable = false; sysPara->status.lastPhaseFault = 0; sysPara->status.phaseErrorCnt = 0; if(sysPara->status.lastHighVoltageFault && !(sysPara->status.statWarn & WARN_STATUS_POWER_MON)){ sysPara->status.lastHighVoltageFault = false; flagOfClearHighVltageWarnning = true; } if(sysPara->status.gearPumpRunStopFlag && pushButtonFlag) { emit repeatInitedPid(); sysPara->status.gearPumpRunStopFlag = false;//齿轮泵报警恢复 } if((sysPara->devOp->color_flag == 2) ||(sysPara->devOp->color_flag == 1)) { sysPara->devOp->color_flag = 3; sysPara->devOp->controlYellowLight(false); sysPara->devOp->controlRedLight(false); } sysPara->status.visocityValueOverflowNum = 0; if(sysPara->status.visocityValueOverflowNum>=MAX_ALLOW_VISICOSITY_OVERFLOW_NUM) // sysPara->status.viscosityFault = 0; sysPara->status.powerOffAfterPhaseFaultAppending = 0; sysPara->status.lastwarmInkPump = 0; sysPara->status.RecycleWarnCnt =0; sysPara->status.lastRecycleWarn =0 ; sysPara->status.powerOffAfterInkOrSOLVEmptyAppending=0; //sysPara->status.lastStatWarn=0; // 机器报故障后,点击故障恢复按钮,再点击打印按钮,“正在喷印中…”字符未立即显示出来,需等待大约10秒才会出现。 //LogInfo::setRunStatusText(tr("故障恢复")); sysPara->status.RecycleWarnCnt=0; sysPara->status.HVFaultCloseEn=0; if(sysPara->status.flagOfPressureFault){ sysPara->status.flagOfPressureFault = false; sysPara->status.isPumpValveControledByHand = false; sysPara->devOp->mainInkCtrl(); emit clearPressureFault(); } if(printintFlag) { sysPara->devOp->highVoltageCtrl(sysPara->para.HighVoltageAmplitude); } } } extern int baudRateValue; void MainWidget::UpdateUIVersion(){ int fpgaType = sysPara->status.fpgaVersionNum>>12; QString fpgaVersion; if(sysPara->status.build_dat.builTime != 0) { fpgaVersion = QString::number(sysPara->status.build_dat.builTime); } else if(fpgaType == 6 || fpgaType == 8){ fpgaVersion = "72"; }else if(fpgaType == 1 || fpgaType == 2){ fpgaVersion = "67"; } fpgaVersion = fpgaVersion + QString("_F%1.%2.%3").arg(sysPara->status.fpgaVersionNum >> 12) .arg((sysPara->status.fpgaVersionNum>>8) & 0x0f).arg(sysPara->status.fpgaVersionNum&0xff); QString STM32Ver = QString("S:%1.%2.%3_B%4").arg((sysPara->status.stm32Verion>>16)&0x7F) .arg((sysPara->status.stm32Verion>>8) & 0xFF).arg(sysPara->status.stm32Verion&0xFF).arg(baudRateValue); 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)); LogInfo::showVerionInformation(Mac,VernonBach,fpgaVersion,STM32Ver); }