0
votes

Bear with me as I am very new to GTK and GDK.

I am trying to cycle through several images, make modifications to them (draw a circle at various points), and take user input from stdin.

I wrote C++ classes to wrap around the GTK framework so I can simplify image manipulation. I am currently opening individual windows with each image, asking for input, closing that window and then opening the next.

I can do everything just fine except get the window to close programmatically, and having the user do it isn't acceptable (ie too tedious). Below is the code that opens and closes the window.

void PixelImage::show() {
  gtk_widget_show_all(this->window);
  gtk_main();
}

void PixelImage::close() {
  gtk_window_close((GtkWindow*)this->window);
}

PixelImage::PixelImage(const char *fname) {
  this->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(this->window, "destroy",
                   G_CALLBACK (gtk_main_quit), NULL);

  this->fname = std::string(fname);
  this->image = gtk_image_new_from_file(fname);
  this->pix = gtk_image_get_pixbuf((GtkImage*)this->image);
  this->pixels = gdk_pixbuf_get_pixels(this->pix);
  this->len = gdk_pixbuf_get_byte_length(this->pix);

  this->width  = gdk_pixbuf_get_width(this->pix);
  this->height = gdk_pixbuf_get_height(this->pix);
  this->nchannels = gdk_pixbuf_get_n_channels(this->pix);
  this->rowstride = gdk_pixbuf_get_rowstride(this->pix);

  gtk_container_add(GTK_CONTAINER (this->window), this->image);
}

When close is called after show, the window remains and when I close it, the following error appears.

(img:2173): Gtk-CRITICAL **: gtk_widget_get_realized: assertion 'GTK_IS_WIDGET (widget)' failed

1

1 Answers

0
votes

So I am going to answer my own question. Perhaps there is a better way, which I would love to hear, but this is how I solved it.

I used POSIX Threads where I open a thread that opens the image window and then do other things on the main thread. Then I simply called gtk_main_quit() from the main thread. Then I join with the window bearing thread. Here is the code.

static void* gtkStarter(void * a) {
  gtk_main();
  return NULL;
}

void PixelImage::show() {
  gtk_widget_show_all(this->window);
  pthread_create(&this->pp, NULL, gtkStarter, NULL);
}

void PixelImage::close() {
  gtk_main_quit();
  pthread_join(this->pp, NULL);
}

It seems to work pretty well.