[gtkmm-documentation] Improve the builder examples



commit 8c8d244a9dd03cc725700ca942929151bdf5aa3b
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Sun Oct 25 11:44:40 2020 +0100

    Improve the builder examples
    
    Read the .glade file in a Gio::Application::signal_activate() handler.

 examples/book/builder/basic/main.cc   |  79 ++++++++++++-------------
 examples/book/builder/derived/main.cc | 108 +++++++++++++++++-----------------
 2 files changed, 91 insertions(+), 96 deletions(-)
---
diff --git a/examples/book/builder/basic/main.cc b/examples/book/builder/basic/main.cc
index ec782be..575ce0b 100644
--- a/examples/book/builder/basic/main.cc
+++ b/examples/book/builder/basic/main.cc
@@ -1,28 +1,20 @@
 #include <gtkmm.h>
 #include <iostream>
 
+namespace
+{
 Gtk::Dialog* pDialog = nullptr;
+Glib::RefPtr<Gtk::Application> app;
 
-static
 void on_button_clicked()
 {
-  if(pDialog)
+  if (pDialog)
     pDialog->hide(); //hide() will cause Gtk::Application::run() to end.
 }
 
-int main(int argc, char** argv)
+void on_app_activate()
 {
-  auto app = Gtk::Application::create("org.gtkmm.example");
-
-  // The application must be registered when the builder adds widgets from
-  // the basic.glade file.
-  // Calling Gio::Application::register_application() explicitly is necessary
-  // in this example because the .glade file is loaded in the main() function.
-  // There are better ways. See other examples, such as examples/book/buildapp/,
-  // and examples/book/menus/ and examples/book/menus_and_toolbars/.
-  app->register_application();
-
-  //Load the GtkBuilder file and instantiate its widgets:
+  // Load the GtkBuilder file and instantiate its widgets:
   auto refBuilder = Gtk::Builder::create();
   try
   {
@@ -31,47 +23,50 @@ int main(int argc, char** argv)
   catch(const Glib::FileError& ex)
   {
     std::cerr << "FileError: " << ex.what() << std::endl;
-    return 1;
+    return;
   }
   catch(const Glib::MarkupError& ex)
   {
     std::cerr << "MarkupError: " << ex.what() << std::endl;
-    return 1;
+    return;
   }
   catch(const Gtk::BuilderError& ex)
   {
     std::cerr << "BuilderError: " << ex.what() << std::endl;
-    return 1;
+    return;
   }
 
-  //Get the GtkBuilder-instantiated Dialog:
+  // Get the GtkBuilder-instantiated dialog:
   pDialog = refBuilder->get_widget<Gtk::Dialog>("DialogBasic");
-
-  int status = 1;
-  if (pDialog)
+  if (!pDialog)
   {
-    //Get the GtkBuilder-instantiated Button, and connect a signal handler:
-    auto pButton = refBuilder->get_widget<Gtk::Button>("quit_button");
-    if(pButton)
-    {
-      pButton->signal_clicked().connect( sigc::ptr_fun(on_button_clicked) );
-    }
+    std::cerr << "Could not get the dialog" << std::endl;
+    return;
+  }
 
-    // All widgets must be deleted before app->run() returns.
-    // This is yet another reason why you should usually not use the builder
-    // in the main() function.
-    pDialog->signal_hide().connect([&refBuilder] ()
-    {
-      delete pDialog;
-      refBuilder.reset();
-    });
+  // Get the GtkBuilder-instantiated button, and connect a signal handler:
+  auto pButton = refBuilder->get_widget<Gtk::Button>("quit_button");
+  if (pButton)
+    pButton->signal_clicked().connect([] () { on_button_clicked(); });
 
-    // We can call add_window() before run() because we have registered the
-    // application. (run() registers the application, if it has not been done.)
-    app->add_window(*pDialog);
-    pDialog->show();
-    status = app->run(argc, argv);
-  }
+  // It's not possible to delete widgets after app->run() has returned.
+  // Delete the dialog with its child widgets before app->run() returns.
+  pDialog->signal_hide().connect([] () { delete pDialog; });
+
+  app->add_window(*pDialog);
+  pDialog->show();
+}
+} // anonymous namespace
+
+int main(int argc, char** argv)
+{
+  app = Gtk::Application::create("org.gtkmm.example");
+
+  // Instantiate a dialog when the application has been activated.
+  // This can only be done after the application has been registered.
+  // It's possible to call app->register_application() explicitly, but
+  // usually it's easier to let app->run() do it for you.
+  app->signal_activate().connect([] () { on_app_activate(); });
 
-  return status;
+  return app->run(argc, argv);
 }
diff --git a/examples/book/builder/derived/main.cc b/examples/book/builder/derived/main.cc
index 317402e..6ddca5d 100644
--- a/examples/book/builder/derived/main.cc
+++ b/examples/book/builder/derived/main.cc
@@ -18,45 +18,23 @@
 #include <iostream>
 #include <cstring>
 
-// Not really used anywhere, but force an instance to be created.
-DerivedButton* my_globally_accessible_button = nullptr;
-
-int main(int argc, char** argv)
+namespace
 {
-  bool show_icon = false;
-  bool is_glad = true;
-  int argc1 = argc;
-  if (argc > 1)
-  {
-    if (std::strcmp(argv[1], "--glad") == 0)
-    {
-      show_icon = true;
-      is_glad = true;
-      argc1 = 1; // Don't give the command line arguments to Gtk::Application.
-    }
-    else if (std::strcmp(argv[1], "--sad") == 0)
-    {
-      show_icon = true;
-      is_glad = false;
-      argc1 = 1; // Don't give the command line arguments to Gtk::Application.
-    }
-  }
-
-  auto app = Gtk::Application::create("org.gtkmm.example");
+bool show_icon = false;
+bool is_glad = true;
 
-  // The application must be registered when the builder adds widgets from
-  // the derived.glade file.
-  // Calling Gio::Application::register_application() explicitly is necessary
-  // in this example because the .glade file is loaded in the main() function.
-  // There are better ways. See other examples, such as examples/book/buildapp/,
-  // and examples/book/menus/ and examples/book/menus_and_toolbars/.
-  app->register_application();
+DerivedDialog* pDialog = nullptr;
+Glib::RefPtr<Gtk::Application> app;
 
+void on_app_activate()
+{
   // Create a dummy instance before the call to refBuilder->add_from_file().
   // This creation registers DerivedButton's class in the GType system.
-  my_globally_accessible_button = new DerivedButton();
+  // This is necessary because DerivedButton contains user-defined properties
+  // (Glib::Property) and is created by Gtk::Builder.
+  static_cast<void>(DerivedButton());
 
-  //Load the Glade file and instantiate its widgets:
+  // Load the GtkBuilder file and instantiate its widgets:
   auto refBuilder = Gtk::Builder::create();
   try
   {
@@ -65,44 +43,66 @@ int main(int argc, char** argv)
   catch(const Glib::FileError& ex)
   {
     std::cerr << "FileError: " << ex.what() << std::endl;
-    return 1;
+    return;
   }
   catch(const Glib::MarkupError& ex)
   {
     std::cerr << "MarkupError: " << ex.what() << std::endl;
-    return 1;
+    return;
   }
   catch(const Gtk::BuilderError& ex)
   {
     std::cerr << "BuilderError: " << ex.what() << std::endl;
-    return 1;
+    return;
   }
 
-  //Get the GtkBuilder-instantiated dialog:
-  DerivedDialog* pDialog = nullptr;
+  // Get the GtkBuilder-instantiated dialog:
   if (show_icon)
     pDialog = Gtk::Builder::get_widget_derived<DerivedDialog>(refBuilder, "DialogDerived", is_glad);
   else
     pDialog = Gtk::Builder::get_widget_derived<DerivedDialog>(refBuilder, "DialogDerived");
 
-  int status = 1;
-  if (pDialog)
+  if (!pDialog)
   {
-    // All widgets must be deleted before app->run() returns.
-    // This is yet another reason why you should usually not use the builder
-    // in the main() function.
-    pDialog->signal_hide().connect([pDialog, &refBuilder] ()
-    {
-      delete pDialog;
-      refBuilder.reset();
-    });
+    std::cerr << "Could not get the dialog" << std::endl;
+    return;
+  }
 
-    // We can call add_window() before run() because we have registered the
-    // application. (run() registers the application, if it has not been done.)
-    app->add_window(*pDialog);
-    pDialog->show();
-    status = app->run(argc1, argv);
+  // It's not possible to delete widgets after app->run() has returned.
+  // Delete the dialog with its child widgets before app->run() returns.
+  pDialog->signal_hide().connect([] () { delete pDialog; });
+
+  app->add_window(*pDialog);
+  pDialog->show();
+}
+} // anonymous namespace
+
+int main(int argc, char** argv)
+{
+  int argc1 = argc;
+  if (argc > 1)
+  {
+    if (std::strcmp(argv[1], "--glad") == 0)
+    {
+      show_icon = true;
+      is_glad = true;
+      argc1 = 1; // Don't give the command line arguments to Gtk::Application.
+    }
+    else if (std::strcmp(argv[1], "--sad") == 0)
+    {
+      show_icon = true;
+      is_glad = false;
+      argc1 = 1; // Don't give the command line arguments to Gtk::Application.
+    }
   }
 
-  return status;
+  app = Gtk::Application::create("org.gtkmm.example");
+
+  // Instantiate a dialog when the application has been activated.
+  // This can only be done after the application has been registered.
+  // It's possible to call app->register_application() explicitly, but
+  // usually it's easier to let app->run() do it for you.
+  app->signal_activate().connect([] () { on_app_activate(); });
+
+  return app->run(argc1, argv);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]