如何使用Cairo和Gtk3在GtkDrawingArea中绘制线

问题描述 投票:4回答:5

[有人可以给我展示一个最小的工作示例,该示例在Ct上将C语言用于Cairo与Gtk3在GtkDrawingArea中绘制一行。我试图修改Gtk3测试文件夹中的testcairo.c,但无法使其正常工作。请不要在开罗网站上建议教程; Zetcode.com或gnome.org要么不与Gtk3一起使用,要么不是最小的工作示例。

gtk cairo gtk3
5个回答
12
投票

我明白了。关键区别在于,对于gtk + 3,您必须从“绘制”信号处理程序中进行绘制。使用gtk + 2,它来自“ expose-event”信号处理程序。这是一个最小的工作示例:http://www.gtkforums.com/viewtopic.php?f=3&t=988&p=195286=Drawing+with+Cairo+in+GTK3#p195286


6
投票

这是一个完整的工作示例:

  • 确保已安装gtk3-devel(在Fedora #dnf中安装gtk3-devel)

  • 在Ubuntu中:sudo apt install libgtk-3-dev

编译:gcc draw.c pkg-config --cflags gtk+-3.0 --libs gtk+-3.0 -o draw

pkg-config --cflags gtk+-3.0 --libs gtk+-3.0

0
投票

我不明白为什么它不起作用,它应该起作用。

#include <gtk/gtk.h> gboolean draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data) { guint width, height; GdkRGBA color; GtkStyleContext *context; context = gtk_widget_get_style_context (widget); width = gtk_widget_get_allocated_width (widget); height = gtk_widget_get_allocated_height (widget); gtk_render_background(context, cr, 0, 0, width, height); cairo_arc (cr, width/2.0, height/2.0, MIN (width, height) / 2.0, 0, 2 * G_PI); gtk_style_context_get_color (context, gtk_style_context_get_state (context), &color); gdk_cairo_set_source_rgba (cr, &color); gdk_cairo_set_source_rgba (cr, &color); cairo_fill (cr); return FALSE; } gint main(int argc,char *argv[]) { GtkWidget *window, *drawing_area; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); drawing_area = gtk_drawing_area_new(); gtk_container_add (GTK_CONTAINER (window), drawing_area); gtk_widget_set_size_request (drawing_area, 200, 100); g_signal_connect (G_OBJECT (drawing_area), "draw", G_CALLBACK (draw_callback), NULL); gtk_widget_show_all (window); gtk_main (); return 0; }

您可以看到,带有开罗的gtk2与gtk3几乎相同。


0
投票
http://developer.gnome.org/gtk3/3.2/GtkDrawingArea.html

// compila con valac --pkg gtk+-3.0 nombre_archivo.gs uses Gtk Cairo init Gtk.init (ref args) var TestCairo = new Ventana () TestCairo.show_all () Gtk.main () class Ventana : Window area: Gtk.DrawingArea init title = "Test Genie + GTK + Cairo" set_default_size (400, 400) window_position = WindowPosition.CENTER destroy.connect(Gtk.main_quit) // área de dibujo area: Gtk.DrawingArea = new Gtk.DrawingArea () // conecta el área de dibujo al método dibujar area.draw.connect (dibujar) // añade el área de dibujo a la ventana add (area) def dibujar (context : Context) : bool context.set_source_rgba (1, 0, 0, 1) context.set_line_width (2) context.move_to (200, 100) context.line_to (200, 300) context.move_to (100, 200) context.line_to (300, 200) context.stroke () return true

enter image description here中更多Genie + Gtk +开罗的示例


0
投票

是-我同意...看起来应该对我有用。

但是我有一个单独的问题...我试图使用旋转框来控制要绘制多少条“线”(或图案..)。

我已经将信号连接到DrawingArea进行“绘制”,但是当旋转改变时,我不知道如何重新调用“绘制”回调函数?

任何想法?


自己解决了!

需要使用gtk_widget_queue_draw_area()函数。


main.c:

http://genie.webierta.skn1.com

Glade文件

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <gtk/gtk.h>
#include <cairo.h>

GtkWidget *window1;
GtkWidget *fixed1;
GtkWidget *frame1;
GtkWidget *draw1;
GtkWidget *spin1;
GtkWidget *spin2;

GtkBuilder *builder1;


// Neural Network Setup
gint N = 2;             // number of layers (hard-coded for now)
gint n1;                // number of neurons in first layer
gint n2;                // number of neurons in second layer
gint L;                 // index for tracking each neuron layer

// Graphics Plotting Setup
gdouble W = 500.0;          // hard-coded for now
gdouble H = 300.0;          // hard-coded for now
gdouble mx = 20.0;          // fixed x-margin
gdouble my = 20.0;          // fixed y-margin
gdouble X;                  // total "plotting" width
gdouble Y;                  // total "plotting" height
gdouble dx;                 // equal x-spacing between neurons
gdouble dy;                 // equal y-spacing between neurons
gdouble x;
gdouble y;
gdouble r = 20.0;       // radius



/*
    - redraw (on event..?)
 */

static gboolean on_draw1_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data)
{
    cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
    cairo_set_line_width(cr, 1);

    int i = 0;

    // draw first layer neutrons
    L = 0;
    dy = Y / (n1 + 1);
    x = mx + ((L + 1) * dx);    // x-coordinate of given neuron
    for (i = 0; i < n1; i++)
    {
        y = my + ((i + 1) * dy);        // y-coordinate of given neuron
        cairo_move_to(cr, x + r, y);
        cairo_arc(cr, x, y, r, 0.0, 2.0 * M_PI);
        cairo_close_path(cr);
    }

    // draw second layer neutrons
    L = 1;
    dy = Y / (n2 + 1);
    x = mx + ((L + 1) * dx);
    for (i = 0; i < n2; i++)
    {
        y = my + ((i + 1) * dy);
        cairo_move_to(cr, x + r, y);
        cairo_arc(cr, x, y, r, 0.0, 2.0 * M_PI);
        cairo_close_path(cr);
    }

    cairo_stroke(cr);
    //cairo_fill(cr);

    // FALSE -> allow further events
    return FALSE;
}


int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);

    builder1    = gtk_builder_new_from_file("main2.ui");
    window1     = GTK_WIDGET(gtk_builder_get_object(builder1, "window1"));

    fixed1      = GTK_WIDGET(gtk_builder_get_object(builder1, "fixed1"));
    draw1       = GTK_WIDGET(gtk_builder_get_object(builder1, "draw1"));
    spin1       = GTK_WIDGET(gtk_builder_get_object(builder1, "spin1"));
    spin2       = GTK_WIDGET(gtk_builder_get_object(builder1, "spin2"));

    g_signal_connect(window1, "destroy", G_CALLBACK(gtk_main_quit), NULL);




    g_signal_connect(G_OBJECT(draw1), "draw", G_CALLBACK(on_draw1_draw), NULL);
    gtk_widget_add_events(draw1, 0);




    gtk_builder_connect_signals(builder1, NULL);

    g_object_unref(builder1);


    n1 = 3;
    n2 = 2;
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin1), (gdouble)n1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin2), (gdouble)n2);

    X = W - (2 * mx);
    Y = H - (2 * my);
    dx = X / (N + 1);



    gtk_widget_show_all(window1);

    gtk_main();

    return 0;
}

void on_spin1_value_changed(GtkSpinButton *b)
{
    n1 = gtk_spin_button_get_value_as_int(b);
}

void on_spin2_value_changed(GtkSpinButton *b)
{
    n2 = gtk_spin_button_get_value_as_int(b);
}
© www.soinside.com 2019 - 2024. All rights reserved.