Ich ändere die Pixbuf-Daten eines Bildes als Reaktion auf ein Timer-Ereignis, aber die Änderungen erscheinen nur, wenn ich zum Beispiel das Fenster mit einem anderen Fenster verdecke und es dann freilege. Wie kann ich die Änderungen anzeigen lassen, sobald ich sie vorgenommen habe?gtk display geändertes Bild
#include <gtk/gtk.h>
#include <stdlib.h>
#define ROWS 400
#define COLS 400 // must be divisible by 4
#define BYTES_PER_PIXEL 3
typedef struct {
GtkImage *image;
int stride;
} ImageData;
void free_pixels(guchar *pixels, gpointer data) {
free(pixels);
}
void setrgb(guchar *a, int row, int col, int stride,
guchar r, guchar g, guchar b) {
int p = row * stride + col * BYTES_PER_PIXEL;
a[p] = r; a[p+1] = g; a[p+2] = b;
}
int update_pic(gpointer data) {
static int row = 0;
if (row > 100) return FALSE;
ImageData *id = (ImageData*)data;
GdkPixbuf *pb = gtk_image_get_pixbuf(id->image);
guchar *g = gdk_pixbuf_get_pixels(pb);
for (int c = 0; c < 200; c++)
setrgb(g, row, c, id->stride, 255, 0, 0);
row++;
// this is not enough to get it to show the updated picture
gtk_widget_queue_draw(GTK_WIDGET(id->image));
// adding this does not fix it
while (g_main_context_pending(NULL))
g_main_context_iteration(NULL, FALSE);
return TRUE;
}
int main(int argc, char **argv) {
GtkWidget *window, *image;
GdkPixbuf *pb;
guchar *pixels = calloc(ROWS * COLS, BYTES_PER_PIXEL);
ImageData id;
gtk_init(&argc, &argv);
image = gtk_image_new();
id.image = GTK_IMAGE(image);
id.stride = COLS * BYTES_PER_PIXEL; // COLS is divisible by 4
pb = gdk_pixbuf_new_from_data(
pixels,
GDK_COLORSPACE_RGB, // colorspace
0, // has_alpha
8, // bits-per-sample
COLS, ROWS, // cols, rows
id.stride, // rowstride
free_pixels, // destroy_fn
NULL // destroy_fn_data
);
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pb);
g_object_unref(pb); // should I do this?
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "image");
gtk_window_set_default_size(GTK_WINDOW(window), COLS, ROWS);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_container_add(GTK_CONTAINER(window), image);
g_timeout_add(250, // milliseconds
update_pic, // handler function
&id); // data
gtk_widget_show_all(window);
gtk_main();
return 0;
}
IDK GTK, aber normalerweise müssen Sie eine Art "update" -Ereignis für das Fenster generieren. Dies wird normalerweise auch vom Window-Manager generiert, wenn sich der sichtbare Bereich ändert. – Olaf
Wird diese vorherige Frage verwendet? [Wie zu aktualisieren, ein Fenster (Widget) in GTK neu zu zeichnen?] (Http://stackoverflow.com/questions/32308231/how-to-refresh-redraw-a-window-widget-in-gtk) –
Hier ist ein weiterer . [Wie erzwingen Sie eine Bildschirmaktualisierung in GTK 3.8?] (Http://stackoverflow.com/questions/34912757/how-do-you-force-a-screen-refresh-in-gtk-3-8) –