#include "testprintwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include "LogInfo.h" #include "MyInputMethod.h" #include #include #include "scene/PicScheduleShiftItem.h" #include "scene/PicCounterItem.h" #include "Printsetting.h" #pragma execution_character_set("utf-8") TestPrintWidget::TestPrintWidget(QWidget* parent) : QWidget(parent) { // 加载UI文件 ui.setupUi(this); // 关联成员变量到UI控件 // m_TextEdit = ui.m_TextEdit; m_LineEdit = ui.m_LineEdit; pViewer = ui.graphicsView; // 初始化按钮组(互斥) m_ButtonGroup = new QButtonGroup(this); m_ButtonGroup->setExclusive(true); // 添加左侧工具栏按钮到按钮组 m_ButtonGroup->addButton(ui.btnA, 1); m_ButtonGroup->addButton(ui.btnBarcode, 2); m_ButtonGroup->addButton(ui.btn3D, 3); m_ButtonGroup->addButton(ui.btnDate, 4); m_ButtonGroup->addButton(ui.btnNum, 5); m_ButtonGroup->addButton(ui.btnArrow, 6); // m_ButtonGroup->addButton(ui.btnList, 7); dialogSaveFile =new DialogSaveFile(0); dialogFileOperation = new DialogFileOperation(0); m_CreateImageFlag = false; m_pSavePicScene = new QGraphicsScene(); m_pSavePicScene->setSceneRect(QRectF(0, 0, 3200, MAX_PRINT_ROW_NUM)); //生成图片的场景 editMode = SCENE; m_TextEdit = new QTextEdit(0); m_TextEdit->setLineWrapMode(QTextEdit::NoWrap); // 获取文档并设置边距为0 m_TextEdit->document()->setDocumentMargin(0); QFont font; font.setFamily("Dinkie9"); font.setPointSizeF(6.75); m_TextEdit->setFont(font); pPicScene = new PicScene(this); //edit@12-09 pPicScene->setSceneRect(QRectF(0,0, 3999, 32)); ui.graphicsView->setScene(pPicScene); ui.graphicsView->centerOn(0,0); // ui->senceEditOption->bindScene(pPicScene, ui->graphicsView, ui->textEdit); this->pPicScene->setIsdrawBackground(true); // 哪个天才写的?拿view和scene计算一下会死吗? for(int i=0;i<3;i++){ on_enlargeButton_pressed(); } connect(pPicScene,&PicScene::selectionChanged,this,[=]() { getShowSelectItemText(); }); connect(dialogSaveFile,SIGNAL(returnMainWidget(int)),this,SIGNAL(sendButtonClickedSignal(int))); connect(dialogFileOperation,SIGNAL(openFile(QString,bool)),this,SLOT(onFileOpen(QString,bool))); connect(dialogFileOperation,SIGNAL(createSceneImage(QString)),this,SLOT(onCreateSceneImage(QString))); // ========== 连接所有信号槽 ========== // 左侧工具栏按钮组 connect(m_ButtonGroup, QOverload::of(&QButtonGroup::buttonClicked), this, [=](QAbstractButton* btn) { // 该功能会先弹出子界面 if (btn == ui.btnBarcode) return; emit sendButtonClickedSignal(m_ButtonGroup->id(btn)); }); connect(ui.btn3D, &QPushButton::clicked, this, &TestPrintWidget::onBtn3DClicked); // 顶部工具栏按钮 connect(ui.btnSave, &QPushButton::clicked, [this]() { emit sendButtonClickedSignal(8); }); connect(ui.btnListConfig, &QPushButton::clicked, [this]() { emit sendButtonClickedSignal(9); }); connect(ui.btnItemConfig, &QPushButton::clicked, this, &TestPrintWidget::onBtnItemConfigClicked); // 顶部工具按钮 connect(ui.btnCancel, &QPushButton::clicked, [this]() { // emit sendButtonClickedSignal(13); on_delButton_pressed(); }); // 控制区第一行按钮 connect(ui.m_btnLeft_Control1, &QPushButton::clicked, this, &TestPrintWidget::selectPreviousItem); connect(ui.m_btnRight_Control1, &QPushButton::clicked, this, &TestPrintWidget::selectNextItem); // 方向箭头按钮 connect(ui.m_btnUp, &QPushButton::clicked, [this]() { // emit sendButtonClickedSignal(16); on_KeyUp_clicked(); }); connect(ui.m_btnLeft_Arrow, &QPushButton::clicked, [this]() { // emit sendButtonClickedSignal(17); on_KeyLeft_clicked(); }); connect(ui.m_btnRight_Arrow, &QPushButton::clicked, [this]() { // emit sendButtonClickedSignal(18); on_KeyRight_clicked(); }); connect(ui.m_btnDown, &QPushButton::clicked, [this]() { // emit sendButtonClickedSignal(19); on_KeyDown_clicked(); }); connect(ui.btnA,&QPushButton::clicked,[this](){ on_addButton_pressed(SourceType::TEXT); m_LineEdit->setFocus(); }); connect(ui.btnDate,&QPushButton::clicked, this, &TestPrintWidget::addDateItem); connect(ui.btnArrow, &QPushButton::clicked, this, &TestPrintWidget::onBtnArrowClicked); connect(ui.btnNum,&QPushButton::clicked,[this](){ // on_addButton_pressed(); // m_TextEdit->clear(); // emit sendButtonClickedSignal(17); pPicScene->clearSelection(); QFont font("Dinkie9"); int ls = (int)(font.letterSpacing()); CounterViewModel vm; vm.charWidth = 0; vm.enbCustomCharWidth = false; vm.counterType = COUNTER_TYPE_1; vm.digitalNum = 2; vm.letterSpace = ls; emit sig_showEditCounter(vm); }); connect(ui.btnBarcode, &QPushButton::clicked, [this](){ pPicScene->clearSelection(); showBarcodeEditor(); }); // X,Y label connection connect(pPicScene, &PicScene::focusedItemPosChanged, this, &TestPrintWidget::onSceneFocusedItemPosChanged); // 勾选按钮 connect(ui.m_btnCheck, &QPushButton::clicked, [this]() { QMessageBox::StandardButton ret = QMessageBox::Ok; ret = QMessageBox::warning(this, tr("提示"), tr("是否保存文件?"), QMessageBox::Ok | QMessageBox::Cancel); if (ret == QMessageBox::Ok){ on_saveButton_pressed(); } emit sendButtonClickedSignal(20); }); imageLoader = new ImageLoader(); connect(imageLoader, &ImageLoader::accepted, this, &TestPrintWidget::onImageLoaderAccepted); itemEditor = new ItemEditor(); connect(itemEditor, &ItemEditor::accepted, this, &TestPrintWidget::onItemEditorAccepted); connect(&m_barcodeEditor, &BarcodeEditor::accepted, this, &TestPrintWidget::slt_BarCodeItemDone); m_LineEdit->setProperty("Enter replace enter", true); connect(m_LineEdit, &QLineEdit::returnPressed, this, &TestPrintWidget::onLineEditReturnPressed); // 网络通信,暂时屏蔽 // ui.btnList->hide(); } void TestPrintWidget::bindSysPara(SysPara *sysPara) { this->sysPara = sysPara; // 它需要这个 m_barcodeEditor.bindSysPara(sysPara); } TestPrintWidget::~TestPrintWidget() { if(m_pSavePicScene) { delete m_pSavePicScene; } if(m_TextEdit){ delete m_TextEdit; } delete imageLoader; } QPixmap TestPrintWidget::loadIcon(const QString& iconName, const QSize& size) { QString iconPath = QString(":/icons/res/icons/%1.png").arg(iconName); QPixmap pixmap(iconPath); return pixmap.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); } void TestPrintWidget::on_openfileButton_pressed() { pPicScene->clearSelection(); pPicScene->clearFocus(); dialogFileOperation->refreshListView(editMode); dialogFileOperation->exec(); } void TestPrintWidget::addDateItem() { pPicScene->clearSelection(); emit sig_showEditDateTime(DateItemModel::createDefaultReplaceModel(), TextItemModel{}); } QTextEdit* TestPrintWidget::getQTextEdit(){ return m_TextEdit; } PicScene* TestPrintWidget::getPicScene(){ return pPicScene; } void TestPrintWidget::on_enlargeButton_pressed() { // qreal sceneHeight = pPicScene->sceneRect().height(); // qreal viewHeight = 172.0; // qreal scaleFactor = viewHeight / sceneHeight; // qDebug() << pViewer->devicePixelRatioFScale(); // qDebug() << pViewer->devicePixelRatioF(); // pViewer->scale(scaleFactor, scaleFactor); // TODO:: 保留,以后真的要用到放大缩小 ((MyView*)pViewer)->ZoomOut(); } void TestPrintWidget::on_addButton_pressed(const SourceType type) { addItemFlag = false; m_LineEdit->setEnabled(true); m_LineEdit->setText(""); pPicScene->clearSelection(); textItem = new PicTextItem(0, 0, type); pPicScene->addItem(textItem); textItem->setSource(QString("")); QList items = pPicScene->items(); if(pPicScene->items().count()>1){ QRectF itemRect= items.at(1)->boundingRect(); textItem->setPos( items.at(1)->scenePos().x()+itemRect.width()+20, items.at(1)->scenePos().y()); } else textItem->setPos(this->pViewer->mapToScene(0,0));//edit@12-07 // textItem->setPlainText("Vernon Bach Printer"); // ui->saveButton->setEnabled(true); textItem->setPlainText(""); textItem->setSelected(true); addItemFlag = true; } void TestPrintWidget::onEditItemDone() { const QString content = m_LineEdit->text(); foreach (QGraphicsItem *item, pPicScene->selectedItems()) { PicTextItem *pTextItem = (PicTextItem *)item; if(pTextItem->sourceType() == SourceType::TEXT) pTextItem->setSource(content); } } void TestPrintWidget::getShowSelectItemText() { //Scene Test ui.m_LineEdit->setEnabled(false); ui.m_LineEdit->setText(""); // 选择最后一个被选中的 item,防一手而已,事实上不应允许多选 // 直接选第一个被选中的 item,也是可以的 auto selectedItems = pPicScene->selectedItems(); PicTextItem* lastSelectedTxtItem = nullptr; for(auto item : selectedItems) { PicTextItem* txtItem = dynamic_cast(item); if(txtItem->sourceType() != SourceType::IMAGE && txtItem->sourceType() != SourceType::CODE && txtItem->sourceType() != SourceType::UNKNOWN) { lastSelectedTxtItem = txtItem; } } if(!lastSelectedTxtItem) { return; } // 对于文本item,将它的文本显示到编辑框 if(lastSelectedTxtItem->sourceType() == SourceType::TEXT) { ui.m_LineEdit->setEnabled(true); m_LineEdit->setText(lastSelectedTxtItem->source().toString()); } // pViewer->centerOn(lastSelectedTxtItem); QString currItemFontFamily = lastSelectedTxtItem->font().family(); QHash fontNameToIndex; fontNameToIndex["WenQuanYi5"] = 0; fontNameToIndex["WenQuanYi7"] = 1; fontNameToIndex["Dinkie9"] = 2; fontNameToIndex["WenQuanYi12"] = 3; fontNameToIndex["WenQuanYi16"] = 4; fontNameToIndex["WenQuanYi24"] = 5; fontNameToIndex["WenQuanYi32"] = 6; if(fontNameToIndex.count(currItemFontFamily) == 0) { return; } // 锁住信号再设置,避免设置后触发 cbResolution 的信号 auto b = ui.cbResolution->blockSignals(true); ui.cbResolution->setCurrentIndex(fontNameToIndex[currItemFontFamily]); ui.cbResolution->blockSignals(b); return; } void TestPrintWidget::on_saveButton_pressed() { pPicScene->clearSelection(); if(xmlfileName.isEmpty()) { qDebug()<<"xml file null"; #ifdef MYSAVEFILEDLG disconnect(dialogSaveFile,SIGNAL(saveFile(QString,bool)),0,0); connect(dialogSaveFile,SIGNAL(saveFile(QString,bool)),this,SLOT(onSaveASFile(QString,bool))); dialogSaveFile->refreshListView(editMode); dialogSaveFile->show(); dialogSaveFile->setEnterFileName(""); #endif } else { pPicScene->update(); saveFile(); if(sysPara){ sysPara->sysFile =xmlfileName; snprintf(sysPara->para.lastOpenedFileName,sizeof(sysPara->para.lastOpenedFileName),"%s",xmlfileName.toLatin1().constData()); } //snprintf(sysPara->para.lastOpenedFileName,sizeof(sysPara->para.lastOpenedFileName),"%s",xmlfileName.toLatin1().constData()); // ui->saveButton->setEnabled(false); // emit fileNameChanged(QFileInfo(xmlfileName).fileName()); } } void TestPrintWidget::saveFile(){ QFile file(xmlfileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { // 只写模式打开文件 qDebug() << QString("Cannot write file %1(%2).").arg(xmlfileName).arg(file.errorString()); return; } QXmlStreamWriter writer(&file); writer.setAutoFormatting(true); // 自动格式化 writer.writeStartDocument("1.0", true); // 开始文档(XML 声明) writer.writeComment(QString::fromLocal8Bit("Vernon Bach graphic scene file")); // 注释 writer.writeDTD(QString::fromLocal8Bit(" ]>")); writer.writeStartElement("VBfiles"); // 开始根元素 writer.writeAttribute("Version", "1.0"); // 属性 QList items = pPicScene->items(); int index=0; foreach (QGraphicsItem *item, items) { PicTextItem *picText = qgraphicsitem_cast(item); writer.writeStartElement("VBfile"); // 开始子元素 writer.writeTextElement(QString::fromLocal8Bit("pointer_x"), QString::fromLocal8Bit("%1").arg(picText->pos().x())); writer.writeTextElement(QString::fromLocal8Bit("pointer_y"), QString::fromLocal8Bit("%1").arg(picText->pos().y())); writer.writeTextElement(QString::fromLocal8Bit("Condition"), QString::fromLocal8Bit("%1").arg(picText->SpecialConditions? 1:0)); writer.writeTextElement(QString::fromLocal8Bit("CatchStartValue"), QString::fromLocal8Bit("%1").arg(picText->CatchCnt1StartValue)); writer.writeTextElement(QString::fromLocal8Bit("CatchValue"), QString::fromLocal8Bit("%1").arg(picText->CatchCnt1CurrValue)); QXmlStreamAttributes attrs; attrs.append("sourceType", QString::number(picText->sourceType())); if(picText->sourceType() != SourceType::UNKNOWN) { picText->saveAttrs(attrs); } writer.writeStartElement("itemAttrs"); writer.writeAttributes(attrs); writer.writeEndElement(); writer.writeTextElement(QString::fromLocal8Bit("html_src"), QString::fromLocal8Bit("my_src")); //Scene Test 内容用pPicScene2 Item的html 其他的位置信息用pPicScene Item if(indextoHtml())); } index++; // writer.writeCDATA((picText->toHtml())); writer.writeEndElement(); // 结束子元素 } writer.writeEmptyElement("PrintSettings"); if(m_printSetting) PrintSettingModel::saveToXml(m_printSetting->model(), writer); writer.writeEndElement(); // 结束根元素 writer.writeEndDocument(); // 结束文档 fsync(file.handle()); file.close(); // 关闭文件 } void TestPrintWidget::onSaveASFile(QString filename,bool Flag){// use for dialogSaveFile class qDebug()<sysFile =xmlfileName; snprintf(sysPara->para.lastOpenedFileName,sizeof(sysPara->para.lastOpenedFileName),"%s",xmlfileName.toLatin1().constData()); } //snprintf(sysPara->para.lastOpenedFileName,sizeof(sysPara->para.lastOpenedFileName),"%s",xmlfileName.toLatin1().constData()); // ui->saveButton->setEnabled(false); // emit fileNameChanged(QFileInfo(xmlfileName).fileName()); } /* * 和DialogFileOperation对接 * */ void TestPrintWidget::onFileOpen(QString filePath,bool reviewFlag){ if(editMode==SCENE) { if(filePath.endsWith(".xml")) { QFile file(filePath); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { // 以只写模式打开文件 xmlfileName=filePath; QXmlStreamReader reader(&file); if(!m_CreateImageFlag) { pPicScene->clear(); pViewer->viewport()->update(); unsigned char SpecialVarEnable = 0; sysPara->devOp->fpgaWr(0xa4b0,(unsigned char *)&SpecialVarEnable,1); } // 解析 XML,直到结束 while (!reader.atEnd()) { // 读取下一个元素 QXmlStreamReader::TokenType nType = reader.readNext(); switch (nType) { case QXmlStreamReader::StartDocument: { // 开始文档 //qDebug() << QString::fromLocal8Bit("********** 开始文档(XML 声明) ********** "); // XML 声明 QString strVersion = reader.documentVersion().toString(); QString strEncoding = reader.documentEncoding().toString(); bool bAlone = reader.isStandaloneDocument(); //qDebug() << QString::fromLocal8Bit("版本:%1 编码:%2 Standalone:%3") // .arg(strVersion).arg(strEncoding).arg(bAlone) << "\r\n"; break; } case QXmlStreamReader::Comment: { // 注释 //qDebug() << QString::fromLocal8Bit("********** 注释 ********** "); QString strComment = reader.text().toString(); //qDebug() << strComment << "\r\n"; break; } case QXmlStreamReader::ProcessingInstruction: { // 处理指令 //qDebug() << QString::fromLocal8Bit("********** 处理指令 ********** "); QString strProcInstr = reader.processingInstructionData().toString(); //qDebug() << strProcInstr << "\r\n"; break; } case QXmlStreamReader::DTD: { // DTD //qDebug() << QString::fromLocal8Bit("********** DTD ********** "); QString strDTD = reader.text().toString(); QXmlStreamNotationDeclarations notationDeclarations = reader.notationDeclarations(); // 符号声明 QXmlStreamEntityDeclarations entityDeclarations = reader.entityDeclarations(); // 实体声明 // DTD 声明 QString strDTDName = reader.dtdName().toString(); QString strDTDPublicId = reader.dtdPublicId().toString(); // DTD 公开标识符 QString strDTDSystemId = reader.dtdSystemId().toString(); // DTD 系统标识符 //qDebug() << QString::fromLocal8Bit("DTD : %1").arg(strDTD); //qDebug() << QString::fromLocal8Bit("DTD 名称 : %1").arg(strDTDName); //qDebug() << QString::fromLocal8Bit("DTD 公开标识符 : %1").arg(strDTDPublicId); //qDebug() << QString::fromLocal8Bit("DTD 系统标识符 : %1").arg(strDTDSystemId); //qDebug() << "\r\n"; break; } case QXmlStreamReader::StartElement: { // 开始元素 QString strElementName = reader.name().toString(); if (QString::compare(strElementName, "VBfiles") == 0) { // 根元素 //qDebug() << QString::fromLocal8Bit("********** 开始元素 ********** "); QXmlStreamAttributes attributes = reader.attributes(); if (attributes.hasAttribute("Version")) { QString strVersion = attributes.value("Version").toString(); //qDebug() << QString::fromLocal8Bit("属性:Version(%1)").arg(strVersion); } parseVbfile(reader, reviewFlag); } break; } case QXmlStreamReader::EndDocument: { //*/*/ 结束文档 //qDebug() << QString::fromLocal8Bit("********** 结束文档 ********** "); break; } } } if (reader.hasError()) { // 解析出错 qDebug() << QString::fromLocal8Bit("错误信息:%1 行号:%2 列号:%3 字符位移:%4").arg(reader.errorString()).arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.characterOffset()); } //qDebug()<<"open done"; file.close(); // 关闭文件 //snprintf(sysPara->para.lastOpenedFileName,sizeof(sysPara->para.lastOpenedFileName),"%s",filePath.toLatin1().constData()); if(!m_CreateImageFlag)//生成图片显示 { if(sysPara) { sysPara->sysFile =filePath; sysPara->loadParaFromFile(); //qDebug()<<"textedit txt mode onFileOpen" << sysPara->sysFile; snprintf(sysPara->para.lastOpenedFileName,sizeof(sysPara->para.lastOpenedFileName),"%s",filePath.toLatin1().constData()); } } } emit sendButtonClickedSignal(20); //打开文件完成跳转到主窗口 } } } extern QStringList stringListRecive; void TestPrintWidget::parseVbfile(QXmlStreamReader &reader, bool loadPrintSetting) { // int textItemPosX; // int textItemPosY; // textItemPosX = picText->pos().x() - pPicScene->itemsBoundingRect().x(); // textItemPosY = picText->pos().y() - pPicScene->itemsBoundingRect().y(); float pos_x,pos_y; bool Condition= false ; int CatchStartValue = -1; int CatchValue = -1; QXmlStreamAttributes itemAttrs; while (!reader.atEnd()) { reader.readNext(); if (reader.isStartElement()) { // 开始元素 QString strElementName = reader.name().toString(); if (QString::compare(strElementName, "VBfile") == 0) { //qDebug() << QString::fromLocal8Bit("********** 开始元素 ********** "); } else if (QString::compare(strElementName, QString("pointer_x")) == 0) { // 方式一 reader.readNext(); if (reader.isCharacters()) { pos_x = reader.text().toString().toDouble(); //qDebug() << QString("pointer_x:%1").arg(reader.text().toString()); } } else if (QString::compare(strElementName, QString("pointer_y")) == 0) { // 方式二 pos_y = reader.readElementText().toDouble(); //qDebug() << QString("pointer_y:%1").arg(reader.readElementText()); } else if (QString::compare(strElementName, QString("Condition")) == 0) { Condition = reader.readElementText().toInt() ? true : false; } else if (QString::compare(strElementName, QString("CatchStartValue")) == 0) { CatchStartValue = reader.readElementText().toInt(); } else if (QString::compare(strElementName, QString("CatchValue")) == 0) { CatchValue = reader.readElementText().toInt(); } else if (QString::compare(strElementName, QString("html_src")) == 0) { //qDebug() << QString("html_src:%1").arg(reader.readElementText()); } else if(strElementName == "itemAttrs") { itemAttrs = reader.attributes(); } else if(strElementName == "PrintSettings" && loadPrintSetting) { // 加载打印设置 QXmlStreamAttributes attrs = reader.attributes(); PrintSettingModel model; PrintSettingModel::loadFromXml(model, attrs); if(m_printSetting) { m_printSetting->setModel(model); m_printSetting->applyPrintSettingsToSysPara(false); } reader.skipCurrentElement(); } } else if (reader.isEntityReference()) { // 实体引用 QString strName = reader.name().toString(); QString strText = reader.text().toString(); //qDebug() << QString("EntityReference : %1(%2)").arg(strName).arg(strText); } else if (reader.isCDATA()) { // CDATA QString strCDATA = reader.text().toString(); //qDebug() << QString("CDATA : %1").arg(strCDATA); PicTextItem *pPictText = nullptr; SourceType sourceType = SourceType::UNKNOWN; bool ok = false; sourceType = SourceType(itemAttrs.value("sourceType").toInt(&ok)); switch(sourceType) { case IMAGE: pPictText = new PicImageItem(0, 0); break; case DATETIME: pPictText = new PicDateItem(); break; case SCHEDULE_SHIFT: pPictText = new PicScheduleShiftItem(); break; case CODE: pPictText = new PicCodeItem(); break; case COUNTER: pPictText = new PicCounterItem(); break; case TEXT: default: pPictText = new PicTextItem(0, 0, sourceType); break; } pPictText->setAttrs(itemAttrs); if(m_CreateImageFlag) { m_pSavePicScene->addItem(pPictText); } else { pPicScene->addItem(pPictText); } QFont font = pPictText->font(); // font.setLetterSpacing(QFont::AbsoluteSpacing,sysPara->para.textEditCharSpace); pPictText->setPos(pos_x,pos_y); pPictText->SpecialConditions = Condition; pPictText->CatchCnt1StartValue = CatchStartValue; pPictText->CatchCnt1CurrValue = CatchValue; itemAttrs.clear(); // Condition= false ; // CatchValue = -1; //LogInfo::setRunStatusText(tr("接收文件解析::2")); if(!sysPara->status.forTemplateUse || m_CreateImageFlag) { pPictText->setHtml(strCDATA); } else { //qDebug() << tr("接收文件解析:"); //LogInfo::setRunStatusText(tr("接收文件解析::3")); //stringListRecive << "aaaa" << "bbbb" << "cccc"; if(strCDATA.contains("#1111") || strCDATA.contains("")) { if(stringListRecive.size() > 0) { if(strCDATA.contains("#1111")) { strCDATA.replace("#1111",stringListRecive.at(0).toStdString().c_str()); } else if(strCDATA.contains("")) { // emit generateQRCode(stringListRecive.at(0)); strCDATA.replace("modbusQR#01.bmp","modbusQR.bmp"); } } } else if(strCDATA.contains("#2222") || strCDATA.contains("")) { if(stringListRecive.size() > 1) { if(strCDATA.contains("#2222")) { strCDATA.replace("#2222",stringListRecive.at(1).toStdString().c_str()); } else if(strCDATA.contains("")) { // emit generateQRCode(stringListRecive.at(1)); strCDATA.replace("modbusQR#02.bmp","modbusQR.bmp"); } } } else if(strCDATA.contains("#3333") || strCDATA.contains("")) { if(stringListRecive.size() > 2) { if(strCDATA.contains("#3333")) { strCDATA.replace("#3333",stringListRecive.at(2).toStdString().c_str()); } else if(strCDATA.contains("")) { // emit generateQRCode(stringListRecive.at(2)); strCDATA.replace("modbusQR#03.bmp","modbusQR.bmp"); } } } pPictText->setHtml(strCDATA); } Condition= false ; CatchValue = -1; CatchStartValue = -1; reader.readNext(); if (reader.isCharacters()) { QString strCharacters = reader.text().toString(); //qDebug() << QString("Characters : %1").arg(strCharacters); } } else if (reader.isEndElement()) { // 结束元素 QString strElementName = reader.name().toString(); if (QString::compare(strElementName, "Blogs") == 0) { //qDebug() << QString::fromLocal8Bit("********** 结束元素 ********** "); break; // 跳出循环(解析 QXmlStreamReader::EndDocument) } else if (QString::compare(strElementName, "Blog") == 0) { //qDebug() << QString::fromLocal8Bit("********** 结束元素 ********** "); } } } } void TestPrintWidget::addCodeItem(QString str) { addItemFlag = false; m_LineEdit->setEnabled(true); m_LineEdit->setText(""); pPicScene->clearSelection(); codeItem_Operation = new PicCodeItem(0, 0, SourceType::CODE); codeItem_Operation->setSource(str); pPicScene->addItem(codeItem_Operation); QList items = pPicScene->items(); if(pPicScene->items().count()>1){ QRectF itemRect= items.at(1)->boundingRect(); codeItem_Operation->setPos( items.at(1)->scenePos().x()+itemRect.width()+20, items.at(1)->scenePos().y()); } else codeItem_Operation->setPos(this->pViewer->mapToScene(0,0));//edit@12-07 codeItem_Operation->setPlainText(""); codeItem_Operation->setSelected(true); addItemFlag = true; } int TestPrintWidget::checkSelectScene() { QList items=pPicScene->items(); int index=-1; //寻找当前选中的图层,没有选中的就不继续处理 for(int i=0;iisSelected()){ index=i; break; } } return index; } PicTextItem *TestPrintWidget::checkSelectItem(PicTextItem* srcItem) { PicTextItem* newItem = nullptr; switch (srcItem->sourceType()) { case IMAGE: newItem = new PicImageItem(0, 0, SourceType::IMAGE); break; case DATETIME: newItem = new PicDateItem(); break; case SCHEDULE_SHIFT: newItem = new PicScheduleShiftItem(); break; case CODE: newItem = new PicCodeItem(0, 0, SourceType::CODE); break; case COUNTER: newItem = new PicCounterItem(); break; case TEXT: case UNKNOWN: default: newItem = new PicTextItem(0, 0, srcItem->sourceType()); break; } return newItem; } bool TestPrintWidget::cacheSelectedLayerForPaste(PicTextItem *srcItem) { if (!srcItem) return false; m_copiedSourceType = srcItem->sourceType(); m_copiedSourceValue = srcItem->source(); m_copiedHtml = srcItem->toHtml(); m_copiedSpecialConditions = srcItem->SpecialConditions; m_copiedCatchCnt1StartValue = srcItem->CatchCnt1StartValue; m_copiedCatchCnt1CurrValue = srcItem->CatchCnt1CurrValue; m_copiedPos = srcItem->pos(); m_copiedAttrs.clear(); m_copiedAttrs.append("sourceType", QString::number(srcItem->sourceType())); if (srcItem->sourceType() != SourceType::UNKNOWN) { srcItem->saveAttrs(m_copiedAttrs); } if (srcItem->sourceType() == SourceType::COUNTER) { auto srcCounter = dynamic_cast(srcItem); if (srcCounter) { m_copiedCounterType = int(srcCounter->counterType()); m_copiedCounterDigitalNum = srcCounter->digitalNum(); m_copiedCounterLetterSpace = srcCounter->letterSpace(); m_copiedCounterFontFamily = srcCounter->font().family(); } } pasteTime = 1; return true; } void TestPrintWidget::pasteCopiedLayer() { PicTextItem tempSrc(nullptr, nullptr, m_copiedSourceType); PicTextItem* newItem = checkSelectItem(&tempSrc); if (!newItem) return; pPicScene->clearSelection(); pPicScene->addItem(newItem); if (m_copiedSourceType != SourceType::UNKNOWN) { newItem->setAttrs(m_copiedAttrs); } newItem->setHtml(m_copiedHtml); // 某些类型需要显式恢复 source 才会正确重绘(如条码/二维码、图片、文本) if (m_copiedSourceType == SourceType::TEXT || m_copiedSourceType == SourceType::IMAGE || m_copiedSourceType == SourceType::CODE) { newItem->setSource(m_copiedSourceValue); } // 计数器单独恢复类型和位数,避免仅靠 attrs 导致内容不完整 if (m_copiedSourceType == SourceType::COUNTER) { auto dstCounter = dynamic_cast(newItem); if (dstCounter) { dstCounter->setCustomFont(m_copiedCounterFontFamily); dstCounter->setLetterSpace(m_copiedCounterLetterSpace); dstCounter->setCounter(static_cast(m_copiedCounterType), m_copiedCounterDigitalNum); } } newItem->SpecialConditions = m_copiedSpecialConditions; newItem->CatchCnt1StartValue = m_copiedCatchCnt1StartValue; newItem->CatchCnt1CurrValue = m_copiedCatchCnt1CurrValue; auto rect = newItem->boundingRect(); // 每次粘贴会往右偏移一次 newItem->setPos(m_copiedPos.x() + rect.width()*pasteTime + 2.0, m_copiedPos.y()); newItem->setSelected(true); pasteTime++; } void TestPrintWidget::onCreateSceneImage(QString filePath) { m_CreateImageFlag = true; m_pSavePicScene->clear(); onFileOpen(filePath,false); m_pSavePicScene->clearSelection(); QSize size(m_pSavePicScene->itemsBoundingRect().width(),m_pSavePicScene->itemsBoundingRect().height()); QImage image(size,QImage::Format_ARGB32); image.fill(0x00ffffff);//填充白色 QPainter painter(&image); m_pSavePicScene->render(&painter,QRectF(),m_pSavePicScene->itemsBoundingRect()); image.save("./printSceneView.png");//图片 m_CreateImageFlag = false; } void TestPrintWidget::on_KeyUp_clicked() { moveSelectedItem(Qt::Key_Up); } void TestPrintWidget::on_KeyLeft_clicked() { moveSelectedItem(Qt::Key_Left); } void TestPrintWidget::on_KeyRight_clicked() { moveSelectedItem(Qt::Key_Right); } void TestPrintWidget::on_KeyDown_clicked() { moveSelectedItem(Qt::Key_Down); } void TestPrintWidget::moveSelectedItem(Qt::Key key) { pViewer->setFocus(); auto selectedItems = pPicScene->selectedItems(); QGraphicsItem* lastItem = nullptr; if(selectedItems.size() >= 1) { lastItem = selectedItems.last(); } if(lastItem) { lastItem->setFocus(); } #ifndef Q_OS_WIN32 //QWSServer::sendKeyEvent(0,Qt::Key_Up,Qt::NoModifier,true,false); //向系统发送键盘事件 MyInputMethod::sendEvent(key, Qt::NoModifier); #endif } void TestPrintWidget::on_delButton_pressed() { //Scene Test int index = checkSelectScene(); if (index < 0) return; foreach (QGraphicsItem *item, pPicScene->selectedItems()) { pPicScene->removeItem(item); delete item; } } void TestPrintWidget::setPrintSettingWidget(PrintSetting *wid) { if(!wid) { qWarning() << "Empty PrintSetting object pointer"; return; } if(m_printSetting) { m_printSetting->disconnect(this); m_printSetting = nullptr; } m_printSetting = wid; connect(m_printSetting, &PrintSetting::sendButtonClickedSignal, this, [this](int i) { if(i == 2) { saveFile(); LogInfo::setRunStatusText("Save print setting."); } }); } bool TestPrintWidget::eventFilter(QObject *watched, QEvent *event) { // 只处理 graphicsView 的事件 if (watched == ui.graphicsView) { // 处理鼠标点击事件 if (event->type() == QEvent::MouseButtonPress) { std::cout<<"MouseButtonPress"<initAndShow(true); #else imageLoader->initAndShow(); #endif } void TestPrintWidget::onImageLoaderAccepted() { QString imgPath = imageLoader->imgPath(); QString htmlImg = QString("").arg(imgPath); pPicScene->clearSelection(); PicTextItem* item = new PicImageItem(0, 0, SourceType::IMAGE); item->setHtml(htmlImg); pPicScene->addItem(item); auto boundingRect = pPicScene->itemsBoundingRect(); item->setPos(boundingRect.right(), 0.0); item->setSelected(true); item->setSource(imgPath); } void TestPrintWidget::onBtnItemConfigClicked() { auto selectedItems = pPicScene->selectedItems(); if(selectedItems.size() != 1) { // TODO:: 事实上不应允许多选 return; } auto item = dynamic_cast(selectedItems[0]); if(item->sourceType() == SourceType::COUNTER) { auto counterItem = dynamic_cast(item); CounterViewModel vm; vm.counterType = counterItem->counterType(); vm.digitalNum = counterItem->digitalNum(); vm.letterSpace = counterItem->letterSpace(); vm.enbCustomCharWidth = false; vm.charWidth = counterItem->charWidth(); emit sig_showEditCounter(vm); return; } // 如果是日期类型,则唤醒DateVarSet if(item->data(0).toString() == "datetime") { // @see TestPrintWidget::addDateItem emit sendButtonClickedSignal(16); return; } // TODO:: 先给文字提供配置功能 if(item->sourceType() == SourceType::UNKNOWN) return; if(item->sourceType() == SourceType::DATETIME) { // @see TestPrintWidget::addDateTimeItem auto dateTimeItem = dynamic_cast(item); emit sig_showEditDateTime(dateTimeItem->model(), dateTimeItem->textItemModel()); return; } if(item->sourceType() == SourceType::SCHEDULE_SHIFT) { auto scheduleItem = dynamic_cast(item); emit sig_showScheduleShiftsEditor(scheduleItem->schedules(), scheduleItem->textItemModel()); return; } if (item->sourceType() == SourceType::CODE) { auto codeItem = dynamic_cast(item); if(!codeItem) return; m_barcodeEditor.bindViewModel(codeItem->barcodeViewModel()); showBarcodeEditor(false); return; } itemEditor->edit(item); #if defined(ARCH_AARCH64) itemEditor->showFullScreen(); #else itemEditor->show(); #endif; } void TestPrintWidget::onItemEditorAccepted() { if(itemEditor->currentItem()->source() == SourceType::UNKNOWN) { // Nothing.... } else { PicTextItem* textItem = itemEditor->currentItem(); textItem->applyModify(); } } void TestPrintWidget::onSceneFocusedItemPosChanged(QPoint p) { ui.m_lblX->setText(QString::asprintf("X:%d", p.x())); ui.m_lblY->setText(QString::asprintf("Y:%d", p.y())); } void TestPrintWidget::on_newfileButton_pressed() { // if (maybeSave()) { pPicScene->clear(); pViewer->viewport()->update(); xmlfileName = ""; if (sysPara) { PrintSettingModel defModel = PrintSettingModel::defPrintSettingModel(); PrintSettingModel::applyToSysPara(defModel, sysPara); if(m_printSetting) m_printSetting->setModel(defModel); } sendButtonClickedSignal(21); //新建文件完成 } void TestPrintWidget::slt_BarCodeItemDone() { auto vm = m_barcodeEditor.viewModel(); // 如果当前选中了一个条形码或二维码,则更新其内容,然后直接返回 bool flag = false; auto selectedItem = pPicScene->selectedItems(); for(auto item : selectedItem) { auto codeItem = dynamic_cast(item); if(codeItem) { codeItem->setBarcodeViewModel(vm); flag = true; } } if(flag) return; if(vm.contentPattern.isEmpty()) { qInfo() << "Empty content pattern, the barcode will not be generated."; return; } // 添加条形码或验证码 pPicScene->clearSelection(); PicCodeItem* item = new PicCodeItem(0, 0, SourceType::CODE); item->setBarcodeViewModel(vm); auto boundingRect = pPicScene->itemsBoundingRect(); pPicScene->addItem(item); item->setPos(boundingRect.right(), 0.0); item->setSelected(true); } QGraphicsItem* findClosestItemToViewCenter(QGraphicsView* view) { if (!view || !view->scene()) return nullptr; // 1. 获取视口中心点(视口坐标)并映射到场景坐标 QPoint viewCenter = view->viewport()->rect().center(); QPointF sceneCenter = view->mapToScene(viewCenter); // 2. 获取场景中所有项 QList items = view->scene()->items(); // 3. 寻找最近项 QGraphicsItem* closestItem = nullptr; qreal minDistSq = std::numeric_limits::max(); for (QGraphicsItem* item : items) { // 可选项:跳过不可见项(根据需求决定) if (!item->isVisible()) continue; // 计算项的场景位置到中心点的平方距离(避免开方,性能更好) QPointF itemPos = item->scenePos(); qreal dx = itemPos.x() - sceneCenter.x(); qreal dy = itemPos.y() - sceneCenter.y(); qreal distSq = dx * dx + dy * dy; if (distSq < minDistSq) { minDistSq = distSq; closestItem = item; } } return closestItem; } void TestPrintWidget::selectItemByDirection(bool forward) { auto selectedItems = pPicScene->selectedItems(); // 如果当前没有选中项,且场景中存在项,则选择距离当前视图中心的项 if(selectedItems.isEmpty() && !pPicScene->items().isEmpty()) { auto closestItem = findClosestItemToViewCenter(pViewer); if(closestItem) { closestItem->setSelected(true); return; } } if(selectedItems.isEmpty()) return; auto currItem = selectedItems.last(); if(!currItem) return; auto items = pPicScene->items(); if(items.size() <= 1) return; std::sort(items.begin(), items.end(), [](QGraphicsItem* a, QGraphicsItem* b) { return a->pos().x() < b->pos().x(); }); auto it = std::find(items.begin(), items.end(), currItem); if(it == items.end()) it = items.begin(); QGraphicsItem* nextItem = nullptr; if(forward) { nextItem = (it + 1 == items.end()) ? items.first() : *(it + 1); } else { nextItem = (it == items.begin()) ? items.last() : *(it - 1); } if(nextItem) { pPicScene->clearSelection(); nextItem->setSelected(true); pViewer->centerOn(nextItem); } } void TestPrintWidget::selectNextItem() { selectItemByDirection(true); } void TestPrintWidget::selectPreviousItem() { selectItemByDirection(false); } void TestPrintWidget::onLineEditReturnPressed() { if(pPicScene->selectedItems().size() != 0) { qDebug() << "Change current item text"; } else { qDebug() << "Add new item text"; } } void TestPrintWidget::on_cbResolution_currentIndexChanged(int index) { constexpr char* IdxToFontFamily[] = {"WenQuanYi5", "WenQuanYi7", "Dinkie9", "WenQuanYi12", "WenQuanYi16", "WenQuanYi24", "WenQuanYi32"}; if(index < 0 || int(ARRAY_SIZE(IdxToFontFamily)) <= index) { qWarning() << "Invalied cbResolution index: " << index; index = std::max(std::min(int(ARRAY_SIZE(IdxToFontFamily) - 1), index), 0); auto b = ui.cbResolution->blockSignals(true); ui.cbResolution->setCurrentIndex(index); ui.cbResolution->blockSignals(b); } auto selectedItems = pPicScene->selectedItems(); qInfo() << "Selected font family: " << IdxToFontFamily[index]; qInfo() << "Selected items count: " << selectedItems.size(); for(auto i : selectedItems) { PicTextItem* item = dynamic_cast(i); // if(item->sourceType() == SourceType::COUNTER && IdxToFontFamily[index] == QString("Dinkie9")) { // item->setCustomFont("WenQuanYi12"); // continue; // } if(item) { item->setCustomFont(IdxToFontFamily[index]); qInfo() << "Item " << item->sourceType() << " set font to " << IdxToFontFamily[index]; } } } void TestPrintWidget::addDateTimeItem(const DateItemModel &model, const TextItemModel& textModel) { // 如果当前选中了一个日期时间item,则直接设置模型 auto selectItems = pPicScene->selectedItems(); if(selectItems.size() == 1) { auto item = dynamic_cast(selectItems[0]); if(item->sourceType() == SourceType::DATETIME) { auto dateTimeItem = dynamic_cast(item); dateTimeItem->setTextItemModel(textModel); dateTimeItem->setModel(model); return; } } QString htmlStr = QString("

"); pPicScene->clearSelection(); PicDateItem* item = new PicDateItem(); item->setHtml(htmlStr); pPicScene->addItem(item); auto boundingRect = pPicScene->itemsBoundingRect(); item->setPos(boundingRect.right(), 0.0); item->setSelected(true); item->setModel(model); } void TestPrintWidget::addScheduleShiftsItem(QVector schedules, TextItemModel txtModel) { // 如果当前选中了一个日期时间item,则直接设置模型 auto selectItems = pPicScene->selectedItems(); if(selectItems.size() == 1) { auto item = dynamic_cast(selectItems[0]); if(item->sourceType() == SourceType::SCHEDULE_SHIFT) { auto scheduleItem = dynamic_cast(item); scheduleItem->setSchedules(schedules); scheduleItem->setTextItemModel(txtModel); return; } } QString htmlStr = QString("

"); pPicScene->clearSelection(); PicScheduleShiftItem* item = new PicScheduleShiftItem(); item->setHtml(htmlStr); pPicScene->addItem(item); auto boundingRect = pPicScene->itemsBoundingRect(); item->setPos(boundingRect.right(), 0.0); item->setSelected(true); item->setSchedules(std::move(schedules)); item->setTextItemModel(txtModel); } void TestPrintWidget::addCounterItem(CounterViewModel vm, QSharedPointer f) { int letterSpace = vm.letterSpace; // 查找当前被选中的 item, 如果存在且类型为计数器,则修改这个计数器而不是新建 QList items=pPicScene->items(); int index=0; bool flag = false; for(int i=0;iisSelected()){ flag = true; break; } } QFont font; if(flag) { auto item = dynamic_cast(items[index]); font = f ? *f : item->font(); font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpace); if(item->sourceType() == SourceType::COUNTER) { auto counterItem = dynamic_cast(item); counterItem->setCounter(static_cast(vm.counterType), vm.digitalNum); counterItem->setLetterSpace(int(font.letterSpacing())); if(vm.enbCustomCharWidth) { counterItem->setCharWidth(vm.charWidth); } } return; } font = f ? *f : QFont("WenQuanYi12"); font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpace); // 创建新的计数器item pPicScene->clearSelection(); PicCounterItem* item = new PicCounterItem(); pPicScene->addItem(item); auto boundingRect = pPicScene->itemsBoundingRect(); item->setPos(boundingRect.right(), 0.0); item->setSelected(true); item->setLetterSpace(static_cast(font.letterSpacing())); // item->setCustomFont(font.family()); item->setCounter(static_cast(vm.counterType), vm.digitalNum); if(vm.enbCustomCharWidth) { item->setCharWidth(vm.charWidth); } } QString TestPrintWidget::currentFile() { return xmlfileName; } void TestPrintWidget::showBarcodeEditor(bool restoreViewModel) { #if defined(ARCH_AARCH64) m_barcodeEditor.setWindowState(Qt::WindowFullScreen); #endif if(restoreViewModel) m_barcodeEditor.restoreViewModel(); m_barcodeEditor.setWindowModality(Qt::WindowModal); m_barcodeEditor.show(); } void TestPrintWidget::onBtnArrowClicked() { pPicScene->clearSelection(); emit sig_showScheduleShiftsEditor(QVector(), TextItemModel()); } void TestPrintWidget::on_btn_copy_clicked() { int index = checkSelectScene(); if (index < 0) { qInfo() << "Not selected any item."; return; } PicTextItem* srcItem = dynamic_cast(pPicScene->items().at(index)); if (!srcItem) { qWarning() << "Cannot cast item type to correct type"; return; } cacheSelectedLayerForPaste(srcItem); } void TestPrintWidget::on_btn_paste_clicked() { pasteCopiedLayer(); }