2

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;
  }
4

5 に答える 5

3

コードが作成するウィンドウのスクリーンショットは次のとおりです。

ウィンドウのスクリーンショット

あなたは正方形を見ることを期待していたと思います。ただし、表示されるのはその正方形の左上だけです。これは、描画領域が非常に小さなスペースを要求し、結果としてウィンドウが小さくなるためです。これは、あなたの素晴らしいアートワークがこの最小サイズのウィンドウに収まるようにクリップされていることを意味します。できることがいくつかあります。

  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 );
    

    これを行うだけで、ウィンドウは最初は元のコードのウィンドウと同じように見えます。ただし、ウィンドウのサイズを手動で変更すると、スクロールされたウィンドウ(したがって描画領域)がウィンドウ内のすべてのスペースを埋めるように拡張されることがわかります。十分に拡大すると、正方形が表示されます。

上記の両方を組み合わせると、最初は最大500x500ピクセルのウィンドウが得られます。サイズを変更すると、描画領域が拡大してウィンドウ全体に表示されます。

gtk_widget_set_size_request描画領域ウィジェットのサイズを設定する呼び出しを追加することもできます。スクロールされたウィンドウのサイズよりも大きく設定すると、スクロールバーが表示されます。

于 2013-01-31T20:57:50.593 に答える
2

描画は完了しましたが、ウィンドウの左上隅にあります。次の2つの呼び出しを追加しましたが、すべて問題ないようです。

gtk_widget_set_hexpand(GTK_WIDGET(swindow), TRUE);  
gtk_widget_set_vexpand(GTK_WIDGET(swindow), TRUE);
于 2012-06-21T15:29:11.823 に答える
1

TRUEコールバックから戻ってon_draw()、デフォルトのハンドラーをブロックしてみてください。おそらく、デフォルトのハンドラーは、図面の上に空のスペースを描画していますか?

于 2012-06-21T08:10:30.033 に答える
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;
  }
于 2012-07-06T00:04:47.397 に答える
-2

私はそれを考え出した。

http://www.gtkforums.com/viewtopic.php?f=3&t=988&p=195381#p195381

于 2012-07-03T23:35:37.530 に答える