c++ - 在没有父窗口的情况下显示 Gtk::FileChooserDialog

标签 c++ gtk freeglut

我正在使用 OpenGL GUI 编写应用程序。在 Windows 上,我使用 GetOpenFilename 允许用户选择文件。

我尝试使用 Gtk::FileChooserDialog(在 this tutorial 之后)为 Gtk 在 Linux 上实现类似的功能。我试图使 Windows 和 Linux 的函数签名保持相同,因此我将示例修改为如下所示:

std::string browseFile( std::string filetypes )
{
    Gtk::Main kit(false);

    Gtk::FileChooserDialog dialog( "Please choose a file",
            Gtk::FILE_CHOOSER_ACTION_OPEN );
//    dialog.set_transient_for( kit.instance() );

    //Add response buttons the the dialog:
    dialog.add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL );
    dialog.add_button( Gtk::Stock::OPEN, Gtk::RESPONSE_OK );

    //Add filters, so that only certain file types can be selected:
    Glib::RefPtr<Gtk::FileFilter> filter_any = Gtk::FileFilter::create();
    filter_any->set_name( "Any files" );
    filter_any->add_pattern( "*" );
    dialog.add_filter( filter_any );

    //Show the dialog and wait for a user response:
    int result = dialog.run();

    //Handle the response:
    switch( result )
    {
        case( Gtk::RESPONSE_OK ):
        {
            std::cout << "Open clicked." << std::endl;

            //Notice that this is a std::string, not a Glib::ustring.
            std::string filename = dialog.get_filename(  );
            std::cout << "File selected: " <<  filename << std::endl;
            return filename;
        }
        case( Gtk::RESPONSE_CANCEL ): { std::cout << "Cancel clicked." << std::endl; break; }
        default: { std::cout << "Unexpected button clicked." << std::endl; break; }
    }
    return std::string( "" );
}

主要区别是我消除了 set_transient_for 位,因为我的主窗口不是由 Gtk 管理的(它是由 freeglut 创建的)。

问题:选择文件后,对话框就卡住了。我的应用程序继续运行,我可以处理选定的文件,只是对话框卡住了。

如何在选择文件后关闭对话框? 我尝试了dialog.hide(),但似乎没有任何效果。我还尝试将特定于 Gtk 的代码包含到此函数中,使 int main() 不受特定于平台的代码的影响。

最佳答案

我决定为此创建重载类。代码如下:

    class FileChooser : public Gtk::FileChooserDialog {
public:

    static std::string getFileName() {
        FileChooser dialog("Select file", Gtk::FILE_CHOOSER_ACTION_OPEN);
        kit.run(dialog);
        std::string ret = dialog.chosenFile;
        return ret;
    }
protected:
    static Gtk::Main kit;
    std::string chosenFile;

    FileChooser(const Glib::ustring& title, Gtk::FileChooserAction action = Gtk::FILE_CHOOSER_ACTION_OPEN) :
    Gtk::FileChooserDialog(title, action) {
        chosenFile = std::string("");
        add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
        add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
        signal_response().connect(sigc::mem_fun(*this,
                &FileChooser::on_my_response));
    }

    void on_my_response(int response_id) {
        chosenFile = get_filename();
        hide();
    }
};
Gtk::Main FileChooser::kit(false);

你可以这样使用它:

std::cout << "File: " << FileChooser::getFileName() << "\n";

关于c++ - 在没有父窗口的情况下显示 Gtk::FileChooserDialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11483529/

相关文章:

c++ - Fopen 没有打开文件,但文件存在

c++ - 我很困惑为什么我的 fillDeck 函数说, "assigning to ' char *' from incompatible type ' const char *”

c - 函数参数的 GTK+ 类型转换样式

将 char 转换为 gchar

c++ - Visual Studio 2015 OpenGL freeglut.dll 链接器错误

opengl - 如何为freeglut编写configure.ac和Makefile.am?

c++ - 关闭 FreeGLUT 的最佳方式是什么?

c++ - 将 initializer_list 分配给 std::array

c++ - 透明度分层窗口白色

php - 今天是否在使用 PHP-GTK?如果是,它用于什么用途或可用于什么用途?