我在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;
}
答案 0 :(得分:3)
以下是代码创建的窗口的屏幕截图:
我想你会期待看到一个正方形。但是,您所看到的只是该广场的左上角。这是因为绘图区域请求了非常小的空间,导致窗口很小。这意味着你的精美艺术品被裁剪成适合这种最小尺寸的窗户。你可以做几件事:
设置包含绘图区域的滚动窗口的最小大小:
gtk_widget_set_size_request( swindow, 500, 500 );
这将导致500 x 500像素的绘图区域可见(这比正方形所需的要多得多)。但是,如果使窗口变大,则绘图区域将不会填充它。
将滚动窗口设置为可以获取所有水平和垂直空间:
gtk_widget_set_hexpand( swindow, TRUE );
gtk_widget_set_vexpand( swindow, TRUE );
如果你这样做,那么窗口最初看起来与原始代码中的窗口相同。但是,如果手动调整窗口大小,则会看到滚动窗口(以及绘图区域)扩展以填充窗口中的所有空间。如果你扩展它,你会看到你的方格。
如果你将上述两个结合起来,那么你将得到一个最初约为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)