【问题标题】:c++ printing more pages with cairo in gtk+c++ 在 gtk+ 中使用 cairo 打印更多页面
【发布时间】:2018-02-19 19:55:20
【问题描述】:

我想就用 gtk+ 打印更多页面寻求帮助。 我把几个例子连在一起,但我只能打印一页。

我在向量中有一些字符串(从零到 50 的数字)。按下按钮后,我想将此字符串打印到几页。 我将此向量传递给回调函数,然后我希望它打印到几页(根据此向量的大小)。

我想打印几页具有相同标题的页面。第一页可以写 0 到 30,第二页可以写 31 到 50。

请一些人帮助我改进我的代码(见下文)来做到这一点。 谢谢大家。

GtkWidget *main_window = NULL;

static void draw_page (GtkPrintOperation *operation, GtkPrintContext *context, int page_nr, GtkWidget *data) {
    printf("DEBUG> draw_page\n");
    std::string* nadpisOdkaz = reinterpret_cast<std::string*>(g_object_get_data(G_OBJECT(data), "nadpisOdkaz"));
    std::vector <std::string>* vektorTextuOdkaz = reinterpret_cast<std::vector <std::string>*>(g_object_get_data(G_OBJECT(data), "vektorTextuOdkaz"));

    std::string teloReportu;
    for (int i = 0; i < vektorTextuOdkaz->size(); i++) {
        teloReportu = teloReportu + vektorTextuOdkaz->at(i).c_str() + "\n";
    }

    PangoFontDescription *desc;
    cairo_t *cr = gtk_print_context_get_cairo_context (context);
    //drawing some image in head
    cairo_surface_t *surf1 = cairo_image_surface_create_from_png("/path/to/some/image.png");
    cairo_set_source_surface(cr, surf1, 10, 0);
    cairo_paint(cr);


    //some bigger text in head
    PangoLayout *nadpisLayout = gtk_print_context_create_pango_layout(context);
    pango_layout_set_text (nadpisLayout, nadpisOdkaz->c_str(), -1);
    desc = pango_font_description_from_string ("sans 28");
    pango_layout_set_font_description (nadpisLayout, desc);
    pango_font_description_free (desc);
    //setting position of printing text in head
    cairo_move_to (cr, 150, 30);
    pango_cairo_layout_path (cr, nadpisLayout);
    //filling with black
    cairo_set_source_rgb (cr, 0, 0, 0);
    cairo_fill (cr);

    //printing rest of text
    PangoLayout* layout =  gtk_print_context_create_pango_layout(context);
    pango_layout_set_text (layout, teloReportu.c_str(), -1);
    desc = pango_font_description_from_string ("sans 18");
    pango_layout_set_font_description (layout, desc);
    pango_font_description_free (desc);
    cairo_move_to (cr, 20, 130);
    pango_cairo_layout_path (cr, layout);
    cairo_set_source_rgb (cr, 0, 0, 0);
    cairo_fill (cr);

    //draw line under head
    cairo_move_to (cr, 10, 120);
    cairo_line_to (cr, 550, 120);
    cairo_stroke (cr);

    g_object_unref (nadpisLayout);
    g_object_unref (layout);
    cairo_surface_destroy(surf1);
}

static GtkPrintSettings *settings = NULL;

static void do_print (GtkWidget* wid, GtkWidget* data) {
    printf("DEBUG> do_print\n");

  GtkPrintOperation *print;
  GtkPrintOperationResult res;

  print = gtk_print_operation_new ();

  if (settings != NULL)
    gtk_print_operation_set_print_settings (print, settings);

    gtk_print_operation_set_n_pages(print, 1);

  g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), data);

  res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, GTK_WINDOW (main_window), NULL);

  if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
    {
      if (settings != NULL)
        g_object_unref (settings);

      settings = GTK_PRINT_SETTINGS(g_object_ref (gtk_print_operation_get_print_settings (print)));
    }

  g_object_unref (print);
}


static GtkPageSetup *page_setup = NULL;

std::string Int2String (int cislo) {
    std::stringstream ss;
    ss << cislo;
    return ss.str();
}

int main (int argc, char *argv[]) {
    //some data to print
    std::string nadpis = "jmeno kategorie";
    std::vector<std::string> vektorTextu;

    for (int i = 0; i < 50; i++) {
        vektorTextu.push_back(Int2String(i));
    }


  GtkWidget *button = NULL;
  GtkWidget *vbox = NULL;

  // Initialize GTK+
  g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
  gtk_init (&argc, &argv);
  g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);

  // Create the main window
  main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_container_set_border_width (GTK_CONTAINER (main_window), 8);
  gtk_window_set_title (GTK_WINDOW (main_window), "Hello World");
  gtk_window_set_position (GTK_WINDOW (main_window), GTK_WIN_POS_CENTER);
  gtk_widget_realize (main_window);
  g_signal_connect (main_window, "destroy", gtk_main_quit, NULL);

  // Create a vertical box with buttons
  vbox = gtk_vbox_new (TRUE, 6);
  gtk_container_add (GTK_CONTAINER (main_window), vbox);

  button = gtk_button_new_from_stock (GTK_STOCK_DIALOG_INFO);

  g_object_set_data(G_OBJECT (main_window), "nadpisOdkaz", (gpointer)&nadpis);
  g_object_set_data(G_OBJECT (main_window), "vektorTextuOdkaz", (gpointer)&vektorTextu);
  g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (do_print), (gpointer) main_window);
  gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);

  button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
  g_signal_connect (button, "clicked", gtk_main_quit, NULL);
  gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);

  // Enter the main loop
  gtk_widget_show_all (main_window);
  gtk_main ();

  return 0;
}

【问题讨论】:

  • 我建议您查看this solution from elementary。它适用于多个页面。
  • 您的问题到底是什么?如果你想有两个页面,那么将 gtk_print_operation_set_n_pages(print, 1) 中的 1 替换为 2。

标签: printing gtk cairo


【解决方案1】:

我现在在 Johnny 和他的链接的帮助下解决了这个问题。 问题是 proc draw_page 仍然读取了向量中的相同元素(如果我已经应用了发布 Uli 的建议)。 所以我添加了一些变量来记住它何时完成。 如果有人在这里有帮助是解决方案:

int counter = 0;
int rowsPerPage = 30;

static void draw_page (GtkPrintOperation *operation, GtkPrintContext *context, int page_nr, GtkWidget *data) {
    printf("DEBUG> draw_page\n");
    std::string* nadpisOdkaz = reinterpret_cast<std::string*>(g_object_get_data(G_OBJECT(data), "nadpisOdkaz"));
    std::vector <std::string>* vektorTextuOdkaz = reinterpret_cast<std::vector <std::string>*>(g_object_get_data(G_OBJECT(data), "vektorTextuOdkaz"));

    std::string teloReportu;
    for (int i = counter * rowsPerPage; i < counter * rowsPerPage + rowsPerPage; i++) {
        teloReportu = teloReportu + vektorTextuOdkaz->at(i).c_str() + "\n";
    }
    ++counter;
    .
    .
    .

并且在 proc do_print 中它只需要知道将要打印多少页:

std::vector <std::string>* vektorTextuOdkaz = reinterpret_cast<std::vector <std::string>*>(g_object_get_data(G_OBJECT(data), "vektorTextuOdkaz"));
    gtk_print_operation_set_n_pages(print, vektorTextuOdkaz->size()/rowsPerPage);

感谢您的帮助。

【讨论】:

    猜你喜欢
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多