79536300

Date: 2025-03-26 11:52:58
Score: 0.5
Natty:
Report link

Since this question existed, I have repeatedly occupied myself with it, because I am also very interested in it. I have gained support here. https://discourse.gnome.org/t/gtk4-screenshot-with-gtksnapshot/27981/3?u=holger The problem is to get a "own" GtkSnapshot, which can then be converted into a GskTexture and printed out accordingly. It is important that the GtkWidget is already drawn.

In this example, I was guided by a contribution from April 2020. https://blog.gtk.org/


#include<gtk/gtk.h>

/* This is the important part */
void demo_snapshot(GtkWidget *widget, GtkSnapshot *snapshot);

void custom_snapshot(GtkWidget *widget) {
    GtkSnapshot *snapshot = gtk_snapshot_new();
    
        demo_snapshot(widget, snapshot);

    int w = gtk_widget_get_width(widget);
    int h = gtk_widget_get_height(widget);

        GskRenderNode *node = gtk_snapshot_free_to_node (snapshot);
    GskRenderer *renderer = gtk_native_get_renderer (gtk_widget_get_native (widget));
    GdkTexture *texture = gsk_renderer_render_texture (renderer,
                                       node,
                                       &GRAPHENE_RECT_INIT (0, 0, w,h ));
    gdk_texture_save_to_png (texture, "screenshot.png");

};

/* From here the GtkWidget to be printed begins*/

#define MY_TYPE_WIDGET (my_widget_get_type())
G_DECLARE_FINAL_TYPE (MyWidget, my_widget, MY, WIDGET, GtkWidget)

GtkWidget *my_widget_new();

/*********************************/

struct _MyWidget
{
    GtkWidget parent_instance;
};

struct _MyWidgetClass
{
    GtkWidgetClass parent_class;
};

G_DEFINE_TYPE(MyWidget, my_widget, GTK_TYPE_WIDGET)


void
demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
{
  GdkRGBA red, green, yellow, blue;
  float w, h;

  gdk_rgba_parse (&red, "red");
  gdk_rgba_parse (&green, "green");
  gdk_rgba_parse (&yellow, "yellow");
  gdk_rgba_parse (&blue, "blue");

  w = gtk_widget_get_width (widget) / 2.0;
  h = gtk_widget_get_height (widget) / 2.0;

  gtk_snapshot_append_color (snapshot, &red,
                             &GRAPHENE_RECT_INIT(0, 0, w, h));
  gtk_snapshot_append_color (snapshot, &green,
                             &GRAPHENE_RECT_INIT(w, 0, w, h));
  gtk_snapshot_append_color (snapshot, &yellow,
                             &GRAPHENE_RECT_INIT(0, h, w, h));
  gtk_snapshot_append_color (snapshot, &blue,
                             &GRAPHENE_RECT_INIT(w, h, w, h));
}


static void click_cb (GtkGestureClick *gesture,
                      int              n_press,
                      double           x,
                      double           y)
{
  GtkEventController *controller = GTK_EVENT_CONTROLLER (gesture);
  GtkWidget *widget = gtk_event_controller_get_widget (controller);

  custom_snapshot(widget);

  if (x < gtk_widget_get_width (widget) / 2.0 &&
      y < gtk_widget_get_height (widget) / 2.0)
     g_print ("Rot!\n");
  else if  (x > gtk_widget_get_width (widget) / 2.0 &&
      y > gtk_widget_get_height (widget) / 2.0)
      g_print ("Blau!\n");
  else if  (x > gtk_widget_get_width (widget) / 2.0 &&
      y < gtk_widget_get_height (widget) / 2.0)
      g_print ("GrĂ¼n!\n");
  else if  (x < gtk_widget_get_width (widget) / 2.0 &&
      y > gtk_widget_get_height (widget) / 2.0)
      g_print ("Gelb!\n");
};

void
demo_measure (GtkWidget      *widget,
              GtkOrientation  orientation,
              int             for_size,
              int            *minimum_size,
              int            *natural_size,
              int            *minimum_baseline,
              int            *natural_baseline)
{
  *minimum_size = 100;
  *natural_size = 200;
};


static void my_widget_dispose(GObject *gobject)
{
    MyWidget *self = MY_WIDGET(gobject);
    G_OBJECT_CLASS (my_widget_parent_class)->dispose (gobject);
};

static void my_widget_class_init (MyWidgetClass *class)
{
    G_OBJECT_CLASS(class)->dispose = my_widget_dispose;
    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
    // hier kein LayoutManager notwendig
    widget_class->snapshot = demo_snapshot;
    widget_class->measure = demo_measure;   

};

static void my_widget_init (MyWidget *self)
{
   
      GtkGesture *controller = gtk_gesture_click_new ();
          g_signal_connect_object (controller, "pressed",             
                            G_CALLBACK (click_cb), NULL,G_CONNECT_DEFAULT);
          gtk_widget_add_controller (GTK_WIDGET(self), GTK_EVENT_CONTROLLER(controller))
};

GtkWidget *my_widget_new()
{
    MyWidget *self;
    self = g_object_new(MY_TYPE_WIDGET,NULL);
    return GTK_WIDGET (self);
};

/************************************************************/

static void activate (GtkApplication *app, gpointer user_data)
{
    GtkWidget *window;
    window = gtk_application_window_new(app);
    GtkWidget *widget = my_widget_new();
    gtk_window_set_child(GTK_WINDOW(window),GTK_WIDGET(widget));
    gtk_window_present(GTK_WINDOW (window));

};

int main (int argc, char **argv)
{
    GtkApplication *app;
    int status;

    app = gtk_application_new("org.gtk.mywidget",
            G_APPLICATION_DEFAULT_FLAGS);
    g_signal_connect(app, "activate", G_CALLBACK(activate),NULL);
    status = g_application_run (G_APPLICATION(app), argc, argv);
    g_object_unref(app);
    return status;
}

enter image description here

Have fun trying.

Reasons:
  • Probably link only (1):
  • Contains signature (1):
  • Long answer (-1):
  • Has code block (-0.5):
Posted by: Holger