我有一个 C 项目(在 Linux 上),它根本不使用 GTK,但我只想使用 GTK 来执行某些特定任务,例如选择文件(文件选择器对话框)。所以我没有 GTK 父窗口,没有 gtk 主循环等,我只想要一个文件选择器对话框,它应该阻止我的程序的执行,直到用户选择一个文件(或取消),然后我不使用 GTK曾经。我尝试过的:
https://developer.gnome.org/gtk3/stable/GtkFileChooserDialog.html
我使用了“典型用法”中的代码,第一个示例。我将 gtk_init(&argc, &argv) 放在程序的开头,当我需要文件选择器时,我使用该示例中的代码调用一个函数(我使用父级作为 NULL,因为没有父级)。结果是窗口闪烁几分之一秒,然后是 SIGSEGV。在此之前我有这样的消息:
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
我已经在 stackoverflow 上阅读了有关此消息的问题/答案,但应用程序崩溃对我来说是更严重的事情。我也尝试过这样写:
gtk_widget_show_all(dialog);
在 gtk_file_chooser_dialog_new() 不会导致崩溃之后,我可以选择该文件,但随后我在 gtk_file_chooser_get_filename() 周围再次出现 SIGSEGV。
当使用gdb时,我得到了这个:
Program received signal SIGSEGV, Segmentation fault.
__GI___pthread_mutex_lock (mutex=0x3c3) at ../nptl/pthread_mutex_lock.c:67
你能帮我看看我犯了什么错误吗?我对GTK编程不太熟悉,所以我尝试使用手册中的示例,但似乎不起作用。预先非常感谢!
最佳答案
没有 gtk 主循环就无法使用小部件。
嗯,看来我错了。谨致诚挚的歉意!我之前实际上已经尝试过这样做,并且结论正是我所描述的。但这个问题最近几天一直困扰着我,所以我做了更多的挖掘和实验,并提出了以下程序:
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
/*
* main.c
* Copyright (C) 2015 John Coppens <john@jcoppens.com>
*
* standalone_filechooser is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* standalone_filechooser is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <gtk/gtk.h>
GtkWidget *
create_filechooser_dialog(char *init_path, GtkFileChooserAction action)
{
GtkWidget *wdg = NULL;
switch (action) {
case GTK_FILE_CHOOSER_ACTION_SAVE:
wdg = gtk_file_chooser_dialog_new("Save file", NULL, action,
"Cancel", GTK_RESPONSE_CANCEL,
"Save", GTK_RESPONSE_OK,
NULL);
break;
case GTK_FILE_CHOOSER_ACTION_OPEN:
wdg = gtk_file_chooser_dialog_new("Open file", NULL, action,
"Cancel", GTK_RESPONSE_CANCEL,
"Open", GTK_RESPONSE_OK,
NULL);
break;
case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
break;
}
return wdg;
}
int main(int argc, char *argv[])
{
GtkWidget *wdg;
char *fname = "";
if (argc == 2)
fname = argv[1];
gtk_init(&argc, &argv);
wdg = create_filechooser_dialog(fname, GTK_FILE_CHOOSER_ACTION_OPEN);
if (gtk_dialog_run(GTK_DIALOG(wdg)) == GTK_RESPONSE_OK) {
printf("%s", gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(wdg)));
return(0);
} else
return (1);
}
您可以从另一个程序(甚至终端)调用该对话框
standalone_filechooser [default file]
如果提供了默认文件
(无括号),则会选择它。如果选择了一个文件,它将打印在 stdout
上,否则程序将返回 error=1
在没有主窗口的情况下运行小部件仍然存在一个小问题,这会导致消息发送到 stderr
:GtkDialog 在没有 transient 父窗口的情况下映射。这是不鼓励的
。我认为这确实是一个错误(在更新版本的 gtk3 中是 it might be solved)。由于消息发送到 stderr
,因此不会干扰正常使用。
关于c - 非 GTK 应用程序中的 GTK+3 文件选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30751178/