Терпите меня, потому что я новичок в GTK и GDK.
Я пытаюсь перебрать несколько изображений, внести в них изменения (нарисовать круг в разных точках) и принять пользовательский ввод из stdin.
Я написал классы C ++ для работы с GTK, чтобы упростить манипулирование изображениями. В настоящее время я открываю отдельные окна с каждым изображением, запрашиваю ввод, закрываю это окно и затем открываю следующее.
Я могу делать все просто отлично, за исключением того, что окно закрывается программным способом, и когда пользователь делает это, это недопустимо (то есть слишком утомительно). Ниже приведен код, который открывает и закрывает окно.
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);
}
Когда close вызывается после show, окно остается, а когда я закрываю его, появляется следующая ошибка.
(img: 2173): Gtk-CRITICAL **: gtk_widget_get_realized: утверждение ‘GTK_IS_WIDGET (widget)’ не выполнено
Поэтому я собираюсь ответить на свой вопрос. Возможно, есть лучший способ, который я хотел бы услышать, но я решил это.
Я использовал потоки POSIX, где я открываю поток, который открывает окно изображения, а затем делаю другие вещи в основном потоке. Тогда я просто вызвал gtk_main_quit () из основного потока. Тогда я присоединяюсь с оконной несущей нитью. Вот код
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);
}
Кажется, работает довольно хорошо.