我正在重用GTK +中的模态对话框 - 我使用gtk_window_set_transient_for
设置它的父对话框,运行它,然后将其父级重置为另一个对话框并再次运行它。
在Linux上一切都很好但是在MS Windows上第二次显示此对话框时,所有GTK窗口都混淆了哪一个是活动的。
这是一个测试程序:
#include <gtk/gtk.h>
GtkWidget* main_window;
void run_reused_dialog(
GtkWidget* reused_dialog,
const gchar *parent_title,
const gchar *reused_dialog_title
) {
GtkWidget* parent_dialog = gtk_dialog_new_with_buttons(
parent_title,
GTK_WINDOW(main_window),
GTK_DIALOG_MODAL,
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
NULL
);
gtk_container_add(
GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(parent_dialog))),
gtk_label_new(parent_title)
);
gtk_widget_show_all(parent_dialog);
gtk_dialog_run(GTK_DIALOG(parent_dialog));
gtk_window_set_transient_for(GTK_WINDOW(reused_dialog),GTK_WINDOW(parent_dialog));
gtk_window_set_title(GTK_WINDOW(reused_dialog), reused_dialog_title);
GtkWidget* reused_dialog_label = gtk_label_new(GTK_WINDOW(reused_dialog)->title);
gtk_container_add(
GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(reused_dialog))),
reused_dialog_label
);
gtk_widget_show_all(reused_dialog);
gtk_dialog_run(GTK_DIALOG(reused_dialog));
gtk_widget_hide(reused_dialog);
gtk_container_remove(
GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(reused_dialog))),
reused_dialog_label
);
gtk_widget_hide(parent_dialog);
gtk_widget_destroy(parent_dialog);
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(main_window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(main_window);
/* This is a dialog which will be reused */
GtkWidget* reused_dialog = gtk_dialog_new_with_buttons(
"Reused dialog",
GTK_WINDOW(main_window),
GTK_DIALOG_MODAL,
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
NULL
);
gtk_container_add(
GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(reused_dialog))),
gtk_label_new(GTK_WINDOW(reused_dialog)->title)
);
/* Show first dialog which will display reused dialog */
run_reused_dialog(
reused_dialog,
"First dialog. Click OK to display reused dialog",
"Reused dialog. Click OK to close"
);
/* Show second dialog which will display reused dialog */
run_reused_dialog(
reused_dialog,
"Second dialog. Click OK to display reused dialog",
"Reused dialog. Switch to another application and switch back"
);
gtk_main();
return 0;
}
当显示“重用对话框。切换到另一个应用程序并切换回”对话框时,它会忽略鼠标,但会对键盘输入作出反应。有时切换到另一个应用程序并返回会触发此问题。
问题:
我做错了什么或是Windows GTK端口的错误?
如何在不使用每次使用对话框的情况下解决此问题?
我是否可以重复使用GTK对话框?
示例程序源和带有所需GTK库的已编译可执行文件是here。这是使用i686-pc-mingw32-gcc gtk-reused-dialog.c $(mingw32-pkg-config --cflags --libs gtk+-2.0) -mwindows
在Fedora Linux 15上使用mingw32-gtk2
包进行交叉编译,并安装了它的依赖项。
答案 0 :(得分:1)
这是我的猜测:
当您显示reused_dialog
时,不清楚哪个对话框是模态的(parent_window
仍然存在)。
正确的解决方案:我怀疑如果您重构代码以从回调中显示reused_dialog
(例如,使用response信号),您将获得所需的结果,因为这是< em>通常方式™。
如果您不想重构,可以尝试其中一种解决方案/解决方案(大致按照我认为更好的顺序):
在运行之前始终取消激活reused_dialog
的模态状态; gtk_dialog_run()
will set it再次触发请求:
...
gtk_window_set_modal(GTK_WINDOW(reused_dialog), FALSE);
gtk_dialog_run(GTK_DIALOG(reused_dialog));
...
在运行之前手动抓住焦点reused_dialog
:
...
gtk_grab_add(reused_dialog);
gtk_dialog_run(GTK_DIALOG(reused_dialog));
...
运行后停用parent_window
的模态状态:
...
gtk_dialog_run(GTK_DIALOG(parent_dialog));
gtk_window_set_modal(GTK_WINDOW(parent_dialog), FALSE);
...