Repository navigation
fix: defer printer initialization until ready - #794
Conversation
1. Move heavy printer initialization (DPrinter construction, default printer query) into the async printer info fetch instead of the dialog constructor 2. Add copyPrintSetting helper to deep-copy DPrintPreviewSettingInfo objects, preventing use-after-free of caller-owned settings that may be destroyed before startup completes 3. Queue pending settings, doc name, and print path when the dialog is not yet initialized and apply them after printer info arrives 4. Add isInited guards in event, eventFilter, and setPrintFromPath to avoid touching uninitialized UI during loading 5. Disable scroll area, preview widget, and print button during loading; keep cancel button usable so users can dismiss immediately 6. Use QSharedPointer<DPrinter> ownership to safely discard in-flight results when the dialog closes during construction 7. Pre-initialize QPlatformPrinterSupportPlugin before querying from worker threads to avoid unsynchronized plugin access 8. Add DefaultPrinterInfo struct to carry both printer name and constructed DPrinter from the worker 9. Re-enable and re-enable the disabled unit tests for ut_dprintpreviewdialog with comprehensive coverage of loading state, pending settings, async preview, PDF export, and cancel/reopen scenarios Log: The print preview dialog now opens instantly and validates printer availability in the background Influence: 1. Open the print preview dialog and verify it appears immediately without freezing 2. Confirm the cancel button works while printer info is still loading 3. Test that setDocName, setPrintFromPath, and updateDialogSettingInfo called before show are preserved and applied after startup 4. Verify async preview (setAsynPreview), n-up imposition, and page range settings work when applied before startup 5. Test that closing the dialog during loading does not crash or hang 6. Verify reopening the dialog after cancel reuses the printer correctly 7. Test PDF export after the dialog has fully initialized 8. Verify that installed settings plugins receive pending setting info in correct order fix: 延迟打印机初始化直至就绪 1. 将耗时的打印机初始化(DPrinter 构造、默认打印机查询)从对话框构造函数 移入异步打印机信息获取流程 2. 添加 copyPrintSetting 辅助函数深拷贝 DPrintPreviewSettingInfo 对象, 避免调用方在启动完成前销毁设置对象导致的悬空引用 3. 对话框未初始化时缓存待处理的设置、文档名和打印路径,待打印机信息就绪 后统一应用 4. 在 event、eventFilter 和 setPrintFromPath 中添加 isInited 判断,避免 加载期间操作未初始化的 UI 5. 加载期间禁用滚动区域、预览控件和打印按钮,保持取消按钮可用以便用户随 时关闭 6. 使用 QSharedPointer<DPrinter> 管理所有权,安全释放对话框在构造过程中 关闭时被丢弃的结果 7. 在工作线程查询前预初始化 QPlatformPrinterSupportPlugin,避免插件的非 同步访问 8. 新增 DefaultPrinterInfo 结构,从工作线程同时返回打印机名称和已构造 的 DPrinter 9. 重新启用 ut_dprintpreviewdialog 单元测试,补充加载状态、待处理设置、 异步预览、PDF 导出及取消重开等场景覆盖 Log: 打印预览对话框现可即时打开并在后台校验打印机可用性 Influence: 1. 打开打印预览对话框,确认立即可见且无卡顿 2. 确认在打印机信息加载期间取消按钮可正常使用 3. 测试在 show 之前调用 setDocName、setPrintFromPath 和 updateDialogSettingInfo 时,相关设置被保留并在启动后生效 4. 验证在启动前设置的异步预览(setAsynPreview)、N 合一拼版和页码范围设 置均能正确生效 5. 测试加载期间关闭对话框不会崩溃或卡死 6. 验证取消后重新打开对话框能正确复用打印机 7. 测试对话框完全初始化后的 PDF 导出功能 8. 验证已安装的设置插件按正确顺序收到待处理设置信息 PMS:BUG-375053
|
Warning
详情 {
"export": {
"tests/testcases/widgets/ut_dprintpreviewdialog.cpp": {
"b": [
" painter.drawText(QPointF(20, 20), QStringLiteral(\"PDF export after asynchronous startup\"));"
]
}
}
} |
Reviewer's GuideThe dialog now appears without blocking on printer initialization by fetching printer information and constructing the printer asynchronously, safely buffering pre-startup requests and protecting UI and ownership lifecycles; comprehensive tests cover loading, cancellation, deferred settings, preview behavior, export, and reopening. Sequence diagram for asynchronous print preview dialog startupsequenceDiagram
actor User
participant Dialog as DPrintPreviewDialog
participant Worker as PrinterInfoWorker
participant Plugin as QPlatformPrinterSupportPlugin
participant Printer as DPrinter
participant UI as PrintPreviewUI
User->>Dialog: show()
Dialog->>UI: initui()
Dialog->>UI: Disable scrollarea, preview, and print button
Dialog->>Dialog: fetchPrinterInfo()
Dialog->>Plugin: get()
Dialog->>Worker: Query printer names and default printer
Worker->>Printer: Construct DPrinter()
Worker-->>Dialog: DefaultPrinterInfo(name, printer)
Worker-->>Dialog: Printer names
Dialog->>Dialog: applyPrinterInfo()
Dialog->>UI: Attach printer and initialize data/connections
Dialog->>UI: Enable controls
Dialog-->>User: Ready for printing
Sequence diagram for deferred print preview settingssequenceDiagram
actor Caller
participant Dialog as DPrintPreviewDialog
participant Pending as PendingSettings
participant Startup as PrinterStartup
participant Helper as PreviewSettingsPluginHelper
participant Preview as DPrintPreviewWidget
Caller->>Dialog: setDocName()
Dialog->>Pending: Store pendingDocName
Caller->>Dialog: setPrintFromPath()
Dialog->>Pending: Queue print path in preview
Caller->>Dialog: updateDialogSettingInfo(info)
Dialog->>Dialog: copyPrintSetting(info)
Dialog->>Pending: Store deep copy
Startup-->>Dialog: Printer information ready
Dialog->>Helper: updateSettingInfo(pending setting)
Dialog->>Preview: updatePreview()
Dialog->>Pending: Clear pendingSettings
State diagram for print preview dialog loading and cancellationstateDiagram-v2
[*] --> Loading: show()
Loading --> Loading: setDocName / setPrintFromPath / updateDialogSettingInfo
Loading --> Ready: applyPrinterInfo()
Loading --> Closed: cancelBtn clicked
Ready --> Closed: reject()
Closed --> Loading: show()
Ready --> Ready: setAsynPreview / n-up / page range
Ready --> Closed: finished()
Loading --> [*]: dialog destroyed
Closed --> [*]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
deepin pr auto review🤖 AI 代码审查报告📊 总体评价
🔍 详细分析1. 语法逻辑 ✅评价: 语法正确,逻辑清晰 ✅ 通过 潜在问题: 建议: [] 2. 代码质量 ✅评价: 代码结构清晰,注释完整 ✅ 通过 潜在问题: 建议: ['copyPrintSetting() 可考虑使用模板函数或宏简化重复的 new + static_cast 模式,但当前写法清晰可维护,优先级低'] 3. 代码性能 ✅评价: 性能良好,资源使用合理 ✅ 通过 潜在问题: 建议: [] 4. 代码安全 🔒评价: 存在0个安全漏洞 ✅ 通过
安全漏洞详情: 建议: [] 💡 改进建议代码示例// copyPrintSetting 可选的模板化简化方案(非必须,当前写法已可维护):
template<typename T>
static DPrintPreviewSettingInfo *cloneSetting(const DPrintPreviewSettingInfo *info) {
return new T(*static_cast<const T *>(info));
}
static DPrintPreviewSettingInfo *copyPrintSetting(const DPrintPreviewSettingInfo *info)
{
switch (info->type()) {
case DPrintPreviewSettingInfo::PS_Printer: return cloneSetting<DPrintPreviewPrinterInfo>(info);
case DPrintPreviewSettingInfo::PS_Copies: return cloneSetting<DPrintPreviewCopiesInfo>(info);
case DPrintPreviewSettingInfo::PS_PageRange: return cloneSetting<DPrintPreviewPageRangeInfo>(info);
case DPrintPreviewSettingInfo::PS_Orientation: return cloneSetting<DPrintPreviewOrientationInfo>(info);
case DPrintPreviewSettingInfo::PS_PaperSize: return cloneSetting<DPrintPreviewPaperSizeInfo>(info);
case DPrintPreviewSettingInfo::PS_PrintDuplex: return cloneSetting<DPrintPreviewPrintDuplexInfo>(info);
case DPrintPreviewSettingInfo::PS_NUpPrinting: return cloneSetting<DPrintPreviewNUpPrintInfo>(info);
case DPrintPreviewSettingInfo::PS_PageOrder: return cloneSetting<DPrintPreviewPageOrderInfo>(info);
case DPrintPreviewSettingInfo::PS_ColorMode: return cloneSetting<DPrintPreviewColorModeInfo>(info);
case DPrintPreviewSettingInfo::PS_PaperMargins: return cloneSetting<DPrintPreviewPaperMarginsInfo>(info);
case DPrintPreviewSettingInfo::PS_Scaling: return cloneSetting<DPrintPreviewScalingInfo>(info);
case DPrintPreviewSettingInfo::PS_Watermark: return cloneSetting<DPrintPreviewWatermarkInfo>(info);
default: return nullptr;
}
}本报告由 AI 代码审查工具自动生成 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 18202781743, wjyrich The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Warning
详情 {
"export": {
"tests/testcases/widgets/ut_dprintpreviewdialog.cpp": {
"b": [
" painter.drawText(QPointF(20, 20), QStringLiteral(\"PDF export after asynchronous startup\"));"
]
}
}
} |
|
/forcemerge |
|
This pr force merged! (status: blocked) |
| defaultPrinterWatcher->setFuture(QtConcurrent::run([createPrinter = !printer] { | ||
| qDebug(dPrintPreview) << "Default printer query started"; | ||
| DefaultPrinterInfo info; | ||
| if (createPrinter) { |
There was a problem hiding this comment.
这个一直为true吧,QPrinterInfo::defaultPrinterName没有被请求吧,
| printBtn->setEnabled(false); | ||
|
|
||
| // Initialize Qt's unguarded plugin singleton before querying it in workers. | ||
| QPlatformPrinterSupportPlugin::get(); |
There was a problem hiding this comment.
这个会引起警告吧,是不是要加unused宏,
Log: The print preview dialog now opens instantly and validates printer availability in the background
Influence:
fix: 延迟打印机初始化直至就绪
Log: 打印预览对话框现可即时打开并在后台校验打印机可用性
Influence:
PMS:BUG-375053
Summary by Sourcery
Make the print preview dialog initialize asynchronously while preserving pre-startup state and remaining safe to cancel or close during loading.
Bug Fixes:
Enhancements:
Tests: