0
我正在更改圖像的pixbuf數據以響應計時器事件,但僅當我用另一個窗口覆蓋窗口然後發現它時纔會出現更改。我怎樣才能讓變化一出現就立即出現?gtk顯示修改後的圖像
#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,但通常你必須產生窗口的某種「更新」事件。如果可見區域改變,這通常也由窗口管理器生成。 – Olaf
這是以前的問題嗎? [如何刷新,重畫一個窗口(widget)在gtk?](http://stackoverflow.com/questions/32308231/how-to-refresh-redraw-a-window-widget-in-gtk) –
這是另一個。 [你如何強制屏幕刷新GTK 3.8?](http://stackoverflow.com/questions/34912757/how-do-you-force-a-screen-refresh-in-gtk-3-8) –