#include "testprintwidget.h" #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 "scene/PicSceneLoader.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); // connect(dialogSaveFile,SIGNAL(returnMainWidget(int)),this,SIGNAL(sendButtonClickedSignal(int))); 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, SCENE_MAX_HEIGHT)); ui.graphicsView->setScene(pPicScene); ui.graphicsView->centerOn(0,0); // ui->senceEditOption->bindScene(pPicScene, ui->graphicsView, ui->textEdit); this->pPicScene->setIsdrawBackground(true); connect(pPicScene,&PicScene::selectionChanged,this,[=]() { getShowSelectItemText(); }); // ========== 连接所有信号槽 ========== // 左侧工具栏按钮组 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, &TestPrintWidget::on_saveButton_pressed); connect(ui.btnListConfig, &QPushButton::clicked, [this]() { if(m_printSetting) { m_printSetting->setModel(m_printSettingModel); } 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; vm.cnt1Settings = m_printSettingModel.cnt1Settings; vm.cnt2Settings = m_printSettingModel.cnt2Settings; emit sig_showEditCounter(vm); }); connect(ui.btnBarcode, &QPushButton::clicked, [this](){ pPicScene->clearSelection(); BarcodeViewModel vm; vm.generalSettingsVM = TextItemModel(); vm.contentPattern = ""; vm.counterViewModel = CounterViewModel(); vm.dateViewModel = DateItemModel::createDefaultReplaceModel(); vm.type = BARCODE_TYPE_BARCODE; vm.format.setValue(DlgBarcodeFormatVM()); vm.counterViewModel.cnt1Settings = m_printSettingModel.cnt1Settings; vm.counterViewModel.cnt2Settings = m_printSettingModel.cnt2Settings; showBarcodeEditor(vm); }); // 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){ if(xmlfileName.isEmpty()) { on_saveButton_pressed(); } else { saveFile(); } emit sig_switchWorkFileRequested(xmlfileName); } 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); m_LineEdit->installEventFilter(this); // 网络通信,暂时屏蔽 // ui.btnList->hide(); } void TestPrintWidget::bindSysPara(SysPara *sysPara) { this->sysPara = sysPara; } TestPrintWidget::~TestPrintWidget() { m_LineEdit->removeEventFilter(this); if(m_TextEdit){ delete m_TextEdit; m_TextEdit = nullptr; } if (imageLoader) { delete imageLoader; imageLoader = nullptr; } } 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(); auto myView = dynamic_cast(pViewer); if (myView) myView->ZoomOut(); } void TestPrintWidget::on_addButton_pressed(const SourceType type) { 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); } void TestPrintWidget::onEditItemDone() { const QString content = m_LineEdit->text(); auto selectedItems = pPicScene->selectedItems(); foreach (QGraphicsItem *item, selectedItems) { PicTextItem* pTextItem = dynamic_cast(item); if (pTextItem == nullptr) continue; if(pTextItem->sourceType() == SourceType::TEXT) { if(content.isEmpty()) { pPicScene->removeItem(pTextItem); delete pTextItem; continue; } pTextItem->setSource(content); if(pPicScene->items().count() == 1) { pTextItem->setPos(pTextItem->clampItemPos(pTextItem->scenePos())); qDebug() << "Text item pos: " << pTextItem->pos(); } } } } void TestPrintWidget::getShowSelectItemText() { 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 == nullptr) continue; 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 dialogSaveFile->refreshListView(SCENE); dialogSaveFile->setEnterFileName(""); auto ret = dialogSaveFile->exec(); if(ret == QDialog::Accepted) { auto filename = dialogSaveFile->filename(); if(!filename.endsWith(".xml",Qt::CaseInsensitive)) filename += ".xml"; saveFile(filename); xmlfileName = filename; } #endif } else { pPicScene->update(); saveFile(); } } void TestPrintWidget::saveFile(const QString& filename) { auto fn = filename.isEmpty() ? xmlfileName : filename; PicSceneLoader::saveSceneToXmlFile(fn, pPicScene, &m_printSettingModel); } void TestPrintWidget::onSaveASFile(QString filename,bool Flag) {// use for dialogSaveFile class qDebug()<viewport()->update(); unsigned char SpecialVarEnable = 0; if (sysPara) { sysPara->devOp->fpgaWr(0xa4b0,(unsigned char *)&SpecialVarEnable,1); } bool ok = PicSceneLoader::loadSceneFromFile(filePath, pPicScene, &m_printSettingModel); if(!ok) { qWarning() << "Failed to load file:" << filePath; return; } xmlfileName = filePath; // 将场景中所有项移动,使 pPicScene->itemsBoundingRect() 的左上角对齐到 scene 的 (0,0) // 计算当前边界并做平移(仅在有偏移时执行) QRectF bounds = pPicScene->itemsBoundingRect(); if (!bounds.isNull()) { qreal dx = -bounds.x(); qreal dy = -bounds.y(); if (!qFuzzyIsNull(dx) || !qFuzzyIsNull(dy)) { const auto items = pPicScene->items(); for (QGraphicsItem* it : items) { // 仅移动属于场景根的项,避免重复移动子项 if (!it) continue; QPointF oldPos = it->pos(); it->setPos(oldPos + QPointF(dx, dy)); } } } pViewer->centerOn(0, 0); if(m_printSetting) { m_printSetting->setModel(m_printSettingModel); } qDebug() << "xmlfileName:" << xmlfileName; } 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::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; auto selectedItems = pPicScene->selectedItems(); foreach (QGraphicsItem *item, selectedItems) { pPicScene->removeItem(item); delete item; break; } } 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 && !m_printSetting->isDefaultSettingMode()) { m_printSettingModel = m_printSetting->model(); } }); } bool TestPrintWidget::eventFilter(QObject *watched, QEvent *event) { if(watched == m_LineEdit) { if(event->type() == QEvent::FocusOut) { onEditItemDone(); } } // 其他事件交给父类处理 return QWidget::eventFilter(watched, event); } void TestPrintWidget::showEvent(QShowEvent *event) { QWidget::showEvent(event); pPicScene->update(); auto sceneRect = pPicScene->sceneRect(); // qreal sceneHeight = boundingRect.height() > (qreal)(sysPara->para.canvasHeight) ? SCENE_MAX_HEIGHT : (qreal)(sysPara->para.canvasHeight); int sceneHeight = qMin(int(SCENE_MAX_HEIGHT), (int)(sysPara->para.canvasHeight)); sceneRect.setHeight((qreal)(sceneHeight)); pPicScene->setSceneRect(sceneRect); // TODO:: 添加代码,只在sceneHeight高度为32时,才显示 字体大小选择框中的 32 dot选项 // 以高度为基准 最大化显示场景到 视口 auto viewportHeight = pViewer->viewport()->height(); QTransform transform = pViewer->transform(); auto targetScale = viewportHeight / sceneRect.height(); double currentScale = transform.m11(); double relativeScale = targetScale / currentScale; pViewer->scale(relativeScale, relativeScale); } void TestPrintWidget::onBtn3DClicked() { #if defined(ARCH_AARCH64) imageLoader->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; } PicTextItem* item = dynamic_cast(selectedItems[0]); if (item == nullptr) return; if(item->sourceType() == SourceType::COUNTER) { auto counterItem = dynamic_cast(item); if (counterItem) { CounterViewModel vm; vm.counterType = counterItem->counterType(); vm.digitalNum = counterItem->digitalNum(); vm.letterSpace = counterItem->letterSpace(); vm.enbCustomCharWidth = false; vm.charWidth = counterItem->charWidth(); vm.cnt1Settings = m_printSettingModel.cnt1Settings; vm.cnt2Settings = m_printSettingModel.cnt2Settings; 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); if (dateTimeItem) emit sig_showEditDateTime(dateTimeItem->model(), dateTimeItem->textItemModel()); return; } if(item->sourceType() == SourceType::SCHEDULE_SHIFT) { auto scheduleItem = dynamic_cast(item); if (scheduleItem) emit sig_showScheduleShiftsEditor(scheduleItem->schedules(), scheduleItem->textItemModel()); return; } if (item->sourceType() == SourceType::CODE) { auto codeItem = dynamic_cast(item); if(!codeItem) return; auto vm = codeItem->barcodeViewModel(); vm.counterViewModel.cnt1Settings = m_printSettingModel.cnt1Settings; vm.counterViewModel.cnt2Settings = m_printSettingModel.cnt2Settings; showBarcodeEditor(vm); return; } itemEditor->edit(item); #if defined(ARCH_AARCH64) itemEditor->showFullScreen(); #else itemEditor->setWindowModality(Qt::WindowModal); itemEditor->show(); #endif; } void TestPrintWidget::onItemEditorAccepted() { if(!itemEditor || !itemEditor->currentItem()) return; 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) { m_printSettingModel = PrintSettingModel::defPrintSettingModel(); if(m_printSetting) m_printSetting->setModel(m_printSettingModel); } emit sig_currentFileChanged(); } void TestPrintWidget::slt_BarCodeItemDone() { auto vm = m_barcodeEditor.viewModel(); if(vm.contentPattern.isEmpty()) { qInfo() << "Empty content pattern, the barcode will not be generated."; return; } PicCodeItem* codeItem = nullptr; // 如果当前选中了一个条形码或二维码,则更新其内容,然后直接返回 bool flag = false; auto selectedItem = pPicScene->selectedItems(); for(auto item : selectedItem) { codeItem = dynamic_cast(item); if(codeItem) break; } if(!codeItem) { // 添加条形码或二维码 pPicScene->clearSelection(); codeItem = new PicCodeItem(0, 0, SourceType::CODE); auto boundingRect = pPicScene->itemsBoundingRect(); pPicScene->addItem(codeItem); codeItem->setPos(boundingRect.right(), 0.0); } codeItem->setBarcodeViewModel(vm); codeItem->setSelected(true); m_printSettingModel.cnt1Settings = vm.counterViewModel.cnt1Settings; m_printSettingModel.cnt2Settings = vm.counterViewModel.cnt2Settings; if(m_printSetting) m_printSetting->setModel(m_printSettingModel); } 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::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); } m_printSettingModel.cnt1Settings = vm.cnt1Settings; m_printSettingModel.cnt2Settings = vm.cnt2Settings; } 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); } m_printSettingModel.cnt1Settings = vm.cnt1Settings; m_printSettingModel.cnt2Settings = vm.cnt2Settings; } QString TestPrintWidget::currentFile() { return xmlfileName; } void TestPrintWidget::showBarcodeEditor(const BarcodeViewModel& vm) { #if defined(ARCH_AARCH64) m_barcodeEditor.setWindowState(Qt::WindowFullScreen); #endif m_barcodeEditor.bindViewModel(vm); 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(); }