开罗在可滚动绘图区域

时间:2012-06-21 05:43:46

标签: cairo gtk3

我在Ubuntu 11.04(Natty)上使用gtk + -3.2.4。我正在尝试使用Cairo绘制GtkDrawingArea并使绘图区域可滚动。代码运行没有错误,但没有完成绘图。我做错了什么?

// gcc -Wextra -o scrol `pkg-config --cflags --libs gtk+-3.0` scrol1.c

#include <gtk/gtk.h>

#define WINDOW_WIDTH  800
#define WINDOW_HEIGHT 600

static gboolean draw_cb (GtkWidget *widget, GdkEventExpose *event) 
{
  cairo_t *cr;
  cr = gdk_cairo_create (gtk_widget_get_window (widget));
  cairo_set_source_rgb(cr, 1, 1, 1);
  cairo_paint(cr);
  cairo_set_source_rgb (cr, 0.42, 0.65, 0.80);
  cairo_set_line_width (cr,6);
  cairo_rectangle (cr, 3, 3, 100, 100);
  cairo_stroke (cr); 
  cairo_destroy(cr);
  return FALSE;
}

int main (int argc, char *argv[])
{
  gtk_init (&argc, &argv);
  GtkWidget *window;
  GtkWidget *grid;
  GtkWidget *swindow;
  GtkWidget *viewport;
  GtkWidget *darea;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  grid = gtk_grid_new();
  swindow = gtk_scrolled_window_new (NULL,NULL);
  viewport = gtk_viewport_new (NULL,NULL);
  darea = gtk_drawing_area_new();

  gtk_container_add (GTK_CONTAINER(viewport), darea);
  gtk_container_add (GTK_CONTAINER(swindow), viewport);
  gtk_grid_attach (GTK_GRID(grid), swindow, 0, 1, 1, 2);
  gtk_container_add (GTK_CONTAINER(window), grid);

  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  g_signal_connect (darea, "draw", G_CALLBACK(draw_cb),  NULL);

  gtk_widget_show_all (window);
  gtk_main ();
  return 0;
  }

5 个答案:

答案 0 :(得分:3)

以下是代码创建的窗口的屏幕截图:

Screenshot of window

我想你会期待看到一个正方形。但是,您所看到的只是该广场的左上角。这是因为绘图区域请求了非常小的空间,导致窗口很小。这意味着你的精美艺术品被裁剪成适合这种最小尺寸的窗户。你可以做几件事:

  1. 设置包含绘图区域的滚动窗口的最小大小:

    gtk_widget_set_size_request( swindow, 500, 500 );
    

    这将导致500 x 500像素的绘图区域可见(这比正方形所需的要多得多)。但是,如果使窗口变大,则绘图区域将不会填充它。

  2. 将滚动窗口设置为可以获取所有水平和垂直空间:

    gtk_widget_set_hexpand( swindow, TRUE );
    gtk_widget_set_vexpand( swindow, TRUE );
    

    如果你这样做,那么窗口最初看起来与原始代码中的窗口相同。但是,如果手动调整窗口大小,则会看到滚动窗口(以及绘图区域)扩展以填充窗口中的所有空间。如果你扩展它,你会看到你的方格。

  3. 如果你将上述两个结合起来,那么你将得到一个最初约为500x500像素的窗口。如果您调整它的大小,则绘图区域将展开以填充窗口。

    您还可以添加gtk_widget_set_size_request调用来设置绘图区域小部件的大小。如果您将其设置为大于滚动窗口的大小,那么您将获得滚动条。

答案 1 :(得分:2)

绘图完成,但它只是在窗口的左上角。我添加了以下两个电话,一切看起来都很好:

gtk_widget_set_hexpand(GTK_WIDGET(swindow), TRUE);  
gtk_widget_set_vexpand(GTK_WIDGET(swindow), TRUE);

答案 2 :(得分:1)

尝试从TRUE回调中返回on_draw()以阻止默认处理程序;也许默认处理程序在绘图上绘制空白区域?

答案 3 :(得分:0)

// gcc -Wextra -o grid1 `pkg-config --cflags --libs gtk+-3.0` grid1.c

#include <gtk/gtk.h>

#define WINDOW_WIDTH  200
#define WINDOW_HEIGHT 80

static gboolean draw_cb (GtkWidget *widget, GdkEventExpose *event) 
{
  cairo_t *cr;
  cr = gdk_cairo_create (gtk_widget_get_window (widget));
  cairo_set_source_rgb(cr, 1, 1, 1);
  cairo_paint(cr);
  cairo_set_source_rgb (cr, 0.42, 0.65, 0.80);
  cairo_set_line_width (cr,6);
  cairo_rectangle (cr, 3, 3, 400, 100);
  cairo_stroke (cr);
  cairo_destroy(cr);
  return TRUE;
}

int main (int argc, char *argv[])
{
  gtk_init (&argc, &argv);
  GtkWidget *window;
  GtkWidget *grid;
  GtkWidget *swindow;
  GtkWidget *viewport;
  GtkWidget *darea;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  grid = gtk_grid_new();
  swindow = gtk_scrolled_window_new (NULL,NULL);
  viewport = gtk_viewport_new (NULL,NULL);
  darea = gtk_drawing_area_new();

  gtk_widget_set_size_request (window, 200, 100);
  gtk_widget_set_size_request (darea, 406, 106);

  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
                                  GTK_POLICY_ALWAYS,
                                  GTK_POLICY_NEVER);

  gtk_widget_set_hexpand(GTK_WIDGET(swindow), TRUE);  
  gtk_widget_set_vexpand(GTK_WIDGET(swindow), TRUE);

  gtk_container_add (GTK_CONTAINER(viewport), darea);
  gtk_container_add (GTK_CONTAINER(swindow), viewport);
  gtk_grid_attach (GTK_GRID(grid), swindow, 0, 0, 1, 1);                 
  gtk_container_add (GTK_CONTAINER(window), grid);

  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  g_signal_connect (darea, "draw", G_CALLBACK(draw_cb),  NULL);

  gtk_widget_show_all (window);
  gtk_main ();
  return 0;
  }

答案 4 :(得分:-2)