如何将GTK4 TextView缓冲区文本导出为PDF?
解决gtkmm4导出TextView文本为空白PDF的问题
你的代码创建了Gtk::PrintOperation实例,但没有配置任何要打印/导出的内容,所以导出的PDF是空白的。Gtk::PrintOperation需要通过draw_page信号回调来定义每页要绘制的内容,这是实现PDF导出的核心步骤。
修正后的代码
void MainWindow::export_note() { auto op = Gtk::PrintOperation::create(); // 设置默认页面大小为A4 op->set_default_page_size(Gtk::PaperSize(Gtk::PaperSizeName::A4)); // 获取TextView缓冲区的文本 Glib::ustring content = editor.get_buffer()->get_text(); // 连接draw_page信号,负责绘制每页的内容 op->signal_draw_page().connect([content](const Gtk::PrintOperation*, Gtk::PrintContext& context, int page_nr) { auto cr = context.get_cairo_context(); const double page_width = context.get_width(); const double page_height = context.get_height(); // 配置文本样式:黑色、12号Sans字体 cr->set_source_rgb(0.0, 0.0, 0.0); Pango::FontDescription font_desc("Sans 12"); auto layout = Pango::Layout::create(cr); layout->set_font_description(font_desc); layout->set_text(content); // 设置文本自动换行(宽度限制为页面宽度) const int layout_width = static_cast<int>(page_width * Pango::SCALE); layout->set_width(layout_width); // 简易分页处理:这里只渲染第一页,多页内容需要自行拆分 const int total_text_height = layout->get_pixel_size().get_height(); if (page_nr > 0) { return; } // 设置边距:距左20px,距上20px开始绘制 const double margin = 20.0; cr->move_to(margin, margin); layout->show_in_cairo_context(cr); }); op->set_export_filename("test.pdf"); auto res = op->run(Gtk::PrintOperation::Action::EXPORT); // 你原有的保存文本到文件的逻辑可以保留 cout << save_file_path << endl; ofstream out(work_dir + save_file_path); out << content; out.close(); curr_state = edit_file; }
关键说明
draw_page信号是核心:这个信号会在导出每页PDF时触发,你必须在回调里实现内容的绘制逻辑,否则PrintOperation不知道要输出什么。- 用Pango排版文本:Pango是GTK内置的文本排版库,能自动处理换行、字体渲染,比直接用Cairo绘制文本更高效且美观。
- 分页处理:示例只处理了单页内容,如果你的文本超过一页,需要计算每页能容纳的文本高度,在回调里根据
page_nr参数绘制对应分段的内容。 - 页面配置:可以通过
set_default_page_size设置纸张大小,也可以在回调里自定义边距、字体等样式。
内容的提问来源于stack exchange,提问作者Benson
相关产品推荐
相关产品推荐

