From fc6b52cd32a4e34f1f12b504480614c6bdba5116 Mon Sep 17 00:00:00 2001 From: liyepan Date: Thu, 22 Oct 2026 18:54:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20v0.10.5=20=E2=80=94=E2=80=94=20=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E5=89=8D=E5=85=88=E5=AE=9A=E9=A1=B5=E9=9D=A2=E5=B0=BA?= =?UTF-8?q?=E5=AF=B8=EF=BC=8C=E5=B9=B6=E7=BB=99=E5=AF=BC=E5=87=BA=E8=BF=87?= =?UTF-8?q?=E7=A8=8B=E5=8A=A0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 之前是先渲染文档、后设置页面尺寸;表格用的是百分比宽度, 页面宽度为 0 时插入表格,某些 Qt 构建会在打印排版阶段死循环 - 改成先建 QPdfWriter、量出页面宽高、设好 document 的 pageSize,再开始渲染 - 增加排版结果健全性检查(NaN / 高度 <= 0 直接中止并提示) - 新增导出日志:%APPDATA%/VoiletMark/VoiletMark/export.log(Linux 在 ~/.local/share/...),逐步记录 对话框关闭 / 渲染开始 / 渲染结束 / 写入完成 - 版本 0.10.5 --- README.md | 2 +- VoiletMark.pro | 2 +- src/MainWindow.cpp | 68 ++++++++++++++++++++++++++++++++++++---------- src/MainWindow.h | 1 + 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index a48320d..948a8ef 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 一个轻量的跨平台 Markdown 编辑器,基于 **Qt 5 / C++17** 构建。 -当前版本 **0.10.4**。 +当前版本 **0.10.5**。 ## 界面 diff --git a/VoiletMark.pro b/VoiletMark.pro index 273bc2c..4c8f0d4 100644 --- a/VoiletMark.pro +++ b/VoiletMark.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = VoiletMark -VERSION = 0.10.4 +VERSION = 0.10.5 QT += core gui widgets diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index c6d71bd..2213903 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -688,6 +689,20 @@ bool MainWindow::saveFileAs() return writeToFile(path); } +void MainWindow::logExport(const QString &message) +{ + const QString directory = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + if (directory.isEmpty()) + return; + QDir().mkpath(directory); + + QFile file(QDir(directory).filePath(QStringLiteral("export.log"))); + if (!file.open(QIODevice::Append | QIODevice::Text)) + return; + QTextStream stream(&file); + stream << QDateTime::currentDateTime().toString(Qt::ISODate) << " " << message << "\n"; +} + void MainWindow::exportPdf() { QString suggested = m_currentPath.isEmpty() ? tr("未命名") @@ -702,28 +717,53 @@ void MainWindow::exportPdf() if (!target.endsWith(QStringLiteral(".pdf"), Qt::CaseInsensitive)) target += QStringLiteral(".pdf"); + logExport(QStringLiteral("dialog closed, target=%1").arg(target)); statusBar()->showMessage(tr("正在导出 PDF…")); + QApplication::processEvents(); + + // 用 QPdfWriter 直接写 PDF,不碰任何平台的打印子系统: + // Windows 的打印后台、Linux 的 CUPS 在没有打印机或服务异常时都可能卡住。 + QPdfWriter writer(target); + writer.setPageSize(QPageSize(QPageSize::A4)); + writer.setPageMargins(QMarginsF(16, 16, 16, 16), QPageLayout::Millimeter); + writer.setTitle(QFileInfo(target).completeBaseName()); + + // 先把页面尺寸定下来再渲染:表格用的是百分比宽度, + // 页面宽度为 0 时插入表格会让某些平台的排版循环算不出结果。 + QSizeF pageSize(672.76, 1001.57); + const QRectF paintRect = writer.pageLayout().paintRectPixels(writer.resolution()); + const qreal resolution = qMax(1, writer.resolution()); + if (paintRect.width() > 100 && paintRect.height() > 100) { + const qreal scale = 96.0 / resolution; + pageSize = QSizeF(paintRect.width() * scale, paintRect.height() * scale); + } QTextDocument document; + document.setPageSize(pageSize); + logExport(QStringLiteral("rendering, page size=%1x%2").arg(pageSize.width()).arg(pageSize.height())); + + QApplication::setOverrideCursor(Qt::WaitCursor); MarkdownRenderer::render(m_editor->toPlainText(), &document); + const QSizeF documentSize = document.size(); + logExport(QStringLiteral("rendered, blocks=%1 height=%2") + .arg(document.blockCount()) + .arg(documentSize.height())); - { - // 用 QPdfWriter 直接写 PDF,不碰任何平台的打印子系统: - // Windows 的打印后台、Linux 的 CUPS 在没有打印机或服务异常时都可能卡住。 - QPdfWriter writer(target); - writer.setPageSize(QPageSize(QPageSize::A4)); - writer.setPageMargins(QMarginsF(16, 16, 16, 16), QPageLayout::Millimeter); - writer.setTitle(QFileInfo(target).completeBaseName()); - - const QRectF paintRect = writer.pageLayout().paintRectPixels(writer.resolution()); - const qreal scale = 96.0 / writer.resolution(); - document.setPageSize(QSizeF(paintRect.width() * scale, paintRect.height() * scale)); - - QApplication::setOverrideCursor(Qt::WaitCursor); - document.print(&writer); + if (!qIsFinite(documentSize.width()) || !qIsFinite(documentSize.height()) + || documentSize.height() <= 0) { QApplication::restoreOverrideCursor(); + logExport(QStringLiteral("aborted: bad document size %1x%2") + .arg(documentSize.width()) + .arg(documentSize.height())); + QMessageBox::warning(this, tr("导出失败"), tr("文档排版结果异常,已中止导出。")); + return; } + document.print(&writer); + QApplication::restoreOverrideCursor(); + + logExport(QStringLiteral("printed, size=%1").arg(QFileInfo(target).size())); + if (!QFileInfo::exists(target) || QFileInfo(target).size() <= 0) { QMessageBox::warning(this, tr("导出失败"), tr("没能写出「%1」,换个位置再试一次。") diff --git a/src/MainWindow.h b/src/MainWindow.h index fc2b939..0b2c75d 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -60,6 +60,7 @@ private: QStringList scanFolder() const; void setSourceModeEnabled(bool enabled); void exportPdf(); + void logExport(const QString &message); // ---- Git ---- void updateGitState();