3 Stimmen

Zeigen Sie Gtk::FileChooserDialog ohne übergeordnetes Fenster an

Ich schreibe eine Anwendung mit einer OpenGL-GUI. Auf Windows verwende ich GetOpenFilename, um dem Benutzer die Dateiauswahl zu ermöglichen.

Ich habe versucht, eine ähnliche Funktionalität für Linux für Gtk zu implementieren, indem ich Gtk::FileChooserDialog verwende (nach diesem Tutorial). Ich versuche, die Funktionssignatur für Windows und Linux gleich zu halten, daher habe ich das Beispiel angepasst, um so auszusehen:

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

    Gtk::FileChooserDialog dialog( "Bitte wählen Sie eine Datei",
            Gtk::FILE_CHOOSER_ACTION_OPEN );
//    dialog.set_transient_for( kit.instance() );

    //Füge Antwortbuttons zum Dialog hinzu:
    dialog.add_button( Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL );
    dialog.add_button( Gtk::Stock::OPEN, Gtk::RESPONSE_OK );

    //Fügen Sie Filter hinzu, damit nur bestimmte Dateitypen ausgewählt werden können:
    Glib::RefPtr filter_any = Gtk::FileFilter::create();
    filter_any->set_name( "Alle Dateien" );
    filter_any->add_pattern( "*" );
    dialog.add_filter( filter_any );

    //Zeige den Dialog an und warte auf eine Benutzerantwort:
    int result = dialog.run();

    //Behandle die Antwort:
    switch( result )
    {
        case( Gtk::RESPONSE_OK ):
        {
            std::cout << "Geöffnet angeklickt." << std::endl;

            //Beachten Sie, dass dies ein std::string ist, kein Glib::ustring.
            std::string filename = dialog.get_filename(  );
            std::cout << "Ausgewählte Datei: " <<  filename << std::endl;
            return filename;
        }
        case( Gtk::RESPONSE_CANCEL ): { std::cout << "Abbrechen angeklickt." << std::endl; break; }
        default: { std::cout << "Unerwarteter Button-Klick." << std::endl; break; }
    }
    return std::string( "" );
}

Der Hauptunterschied besteht darin, dass ich den Teil set_transient_for eliminiert habe, da mein Hauptfenster nicht von Gtk verwaltet wird (es wird von freeglut erstellt).

Problem: Nachdem ich eine Datei ausgewählt habe, friert der Dialog einfach ein. Meine Anwendung läuft weiter, ich kann die ausgewählte Datei verarbeiten, nur die Dialoge frieren ein.

Wie kann ich das Dialogfeld nach der Dateiauswahl schließen? Ich habe dialog.hide() versucht, aber es scheint keinen Effekt zu haben. Ich versuche auch, den Gtk-spezifischen Code auf diese Funktion zu beschränken und int main() frei von plattformspezifischem Code zu halten.

3voto

Ich habe beschlossen, eine überladene Klasse dafür zu erstellen. Der Code befindet sich unten:

    class FileChooser : public Gtk::FileChooserDialog {
public:

    static std::string getFileName() {
        FileChooser dialog("Datei auswählen", 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);

Du kannst es so nutzen:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X