QT 5.15.2中用QPainter导出PDF触发QPainter::begin()返回false报错
核心故障原因
- 最直接的触发错误:
QPdfWriter pdf("C:");传入的不是合法的PDF文件输出路径,Windows系统下"C:"仅代表盘符根节点,既没有指定具体文件名,也没有拼接成完整的合法文件路径,导致QPdfWriter无法初始化输出流,直接触发QPainter::begin(): Returned false错误,后续所有绘制操作因为painter未激活全部失效。 - 常见权限拦截问题:就算修正路径直接写入C盘根目录,当前应用如果没有管理员权限,根本无法在根目录创建文件,会被系统权限校验拦截,同样会触发文件初始化失败。
- 代码逻辑疏漏:表头位置存在重复绘制bug,原代码中
email和salary两个文本的绘制坐标完全重合;原代码在所有绘制流程走完之前就弹出完成提示框,且没有实现选择“是”之后打开PDF的实际逻辑。 - 模块依赖冗余:导出PDF的功能仅依赖
printsupport模块即可正常运行,multimedia模块和该功能无关,可从项目配置中移除,不影响核心功能。
修正后的可运行代码
void ManageTeachers::on_print_clicked() { // 生成合法的输出路径:存到用户桌面,规避根目录权限问题 QString outputPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/teachers_list.pdf"; QPdfWriter pdf(outputPath); // 设置默认页面大小为A4 pdf.setPageSize(QPageSize(QPageSize::A4)); QPainter painter(&pdf); // 先校验painter是否激活成功,失败直接中断流程 if (!painter.isActive()) { QMessageBox::critical(this, "错误", "PDF文件初始化失败,请检查文件存储权限"); return; } int rowY = 4000; // 绘制标题 painter.setPen(Qt::blue); painter.setFont(QFont("Arial", 30)); painter.drawText(1100, 1200, "List of teachers"); painter.setPen(Qt::black); painter.setFont(QFont("Arial", 15)); // 绘制外框和表头栏 painter.drawRect(100, 100, 7300, 2600); painter.drawRect(0, 3000, 9600, 500); painter.setFont(QFont("Arial", 9)); // 修正表头坐标重叠的问题 painter.drawText(200, 3300, "CIN"); painter.drawText(1300, 3300, "First name"); painter.drawText(2100, 3300, "last name"); painter.drawText(3200, 3300, "phone"); painter.drawText(4500, 3300, "email"); painter.drawText(6300, 3300, "salary"); QSqlQuery query; query.prepare("select * from teacher"); query.exec(); while (query.next()) { painter.drawText(200, rowY, query.value(0).toString()); painter.drawText(1300, rowY, query.value(1).toString()); painter.drawText(2200, rowY, query.value(2).toString()); painter.drawText(3200, rowY, query.value(3).toString()); painter.drawText(4500, rowY, query.value(4).toString()); painter.drawText(6300, rowY, query.value(5).toString()); rowY = rowY + 500; } // 所有绘制完成后再结束painter,完成PDF文件落盘 painter.end(); int reponse = QMessageBox::question(this, "生成PDF", "PDF已保存,是否现在打开?", QMessageBox::Yes | QMessageBox::No); if (reponse == QMessageBox::Yes) { // 调用系统默认PDF阅读器打开生成的文件 QDesktopServices::openUrl(QUrl::fromLocalFile(outputPath)); } }
注意事项
- 代码中使用的
QStandardPaths需要引入头文件<QStandardPaths>,QDesktopServices需要引入头文件<QDesktopServices> - 绘制坐标的单位为文档点,需匹配QPdfWriter设置的页面尺寸,避免内容超出页面边界
- 不要硬编码写入系统盘符根目录的文件路径,否则会频繁触发Windows的权限拦截错误
内容的提问来源于stack exchange,提问作者nermineslimane
相关产品推荐
相关产品推荐

