在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",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包并安装了它的依赖项.
解决方法
>问题与焦点攫取有关;
>窗口小部件仅在模态标志changes its state时调用抓取API;
>平台之间的差异主要是由于实施细节;
>你不能只有一个模态窗口.
在显示reused_dialog时,不清楚哪个对话框是模态的(parent_window仍然存活).
正确的解决方案:我怀疑如果您重构代码以显示来自回调的reused_dialog(例如,使用response信号),您将获得所需的结果,因为这是通常的方法™.
如果您不想重构,可以尝试其中一种解决方案/解决方案(大致按照我认为更好的顺序):
>在运行之前,始终取消激活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); ...