Created
July 24, 2020 05:24
-
-
Save rodolforg/802222eb41287da744646529615d91e2 to your computer and use it in GitHub Desktop.
How to read/parse simple custom properties from glade file for a custom widget in gtkmm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Sample code showing how to read/parse properties from glade file for a custom widget in gtkmm | |
| // | |
| // On linux, you can build it with: | |
| // g++ -o simple simple.cpp `pkg-config --cflags --libs gtkmm-3.0` | |
| #include <gtkmm.h> | |
| #include <iostream> | |
| #include <string> | |
| static Glib::RefPtr<Gtk::Builder> load_interface(const char *filename); | |
| // My custom widget | |
| class MyLabel : public Gtk::Label | |
| { | |
| // my custom property (int) | |
| Glib::Property<int> property_my_max_chars_; | |
| public: | |
| MyLabel() | |
| : Glib::ObjectBase("my_label"), // this way, our class is named gtkmm__CustomObject_my_label for Glib | |
| Gtk::Label(), | |
| property_my_max_chars_(*this, "my_max_chars", 5) // set the property on constructor. | |
| // "my_max_chars" is its name (used by Gtk::Inspector, Gtk::Builder, etc) | |
| // 5 is its default value. Not mandatory, but as it's an int... | |
| { | |
| init(); | |
| } | |
| // constructor used by Gtk::Builder (actually constructor called indirectly from C library) | |
| MyLabel(BaseObjectType* cobject) | |
| : Glib::ObjectBase("my_label"), | |
| Gtk::Label(cobject), | |
| property_my_max_chars_(*this, "my_max_chars", 5) | |
| { | |
| init(); | |
| } | |
| // get/set access to my custom property | |
| Glib::PropertyProxy<int> property_my_max_chars() { return property_my_max_chars_.get_proxy(); } | |
| // get-only access to my custom property | |
| Glib::PropertyProxy_ReadOnly<int> property_my_max_chars() const { return property_my_max_chars_.get_proxy(); } | |
| private: | |
| void init() { | |
| // if someone sets a new value to my custom property... (example: property_my_max_chars() = 4; ) | |
| property_my_max_chars().signal_changed().connect( sigc::mem_fun(*this, &MyLabel::on_my_max_chars_change) ); // could call redact() directly... | |
| property_label().signal_changed().connect( sigc::mem_fun(*this, &MyLabel::on_text_change) ); // could call redact() directly... | |
| redact(); | |
| } | |
| void on_my_max_chars_change() { | |
| redact(); | |
| } | |
| void on_text_change() { | |
| redact(); | |
| } | |
| // limit the string length | |
| void redact() { | |
| std::string label = get_label(); | |
| int max_chars = property_my_max_chars(); | |
| if (max_chars > 0 && label.length() > max_chars) | |
| set_label(label.substr(0, max_chars)); | |
| } | |
| // More Gtk::Builder stuff (actually C++ - C binding) | |
| public: | |
| // Construct a C++ object from a parent (=base) C class object | |
| static Glib::ObjectBase* wrap_new(GObject* o) { | |
| auto obj = new MyLabel(GTK_LABEL(o)); | |
| if (gtk_widget_is_toplevel(GTK_WIDGET(o))) | |
| return obj; | |
| else | |
| return Gtk::manage(obj); | |
| } | |
| // Register a "new" type in Glib and bind it to the C++ wrapper function | |
| static void register_type() { | |
| if (gtype) | |
| return; | |
| MyLabel dummy; | |
| gtype = G_OBJECT_TYPE(dummy.gobj()); | |
| Glib::wrap_register(gtype, MyLabel::wrap_new); | |
| } | |
| private: | |
| static GType gtype; | |
| }; | |
| GType MyLabel::gtype = 0; | |
| int main(int argc, char *argv[]) | |
| { | |
| auto app = Gtk::Application::create(argc, argv,"org.any.my"); | |
| MyLabel::register_type(); | |
| Gtk::Window window; | |
| window.set_default_size(200, 200); | |
| auto refBuilder = load_interface("test_my_label.glade"); | |
| if (!refBuilder) { | |
| std::cerr << "Couldn't load the interface file" << std::endl; | |
| return 1; | |
| } | |
| MyLabel * widget = nullptr; | |
| refBuilder->get_widget("widget_mylabel", widget); | |
| if (!widget) { | |
| std::cerr << "Couldn't find a widget with id ='widget_mylabel'" << std::endl; | |
| return 2; | |
| } | |
| window.add(*widget); | |
| window.show_all(); | |
| return app->run(window); | |
| } | |
| static Glib::RefPtr<Gtk::Builder> load_interface(const char *filename) | |
| { | |
| auto refBuilder = Gtk::Builder::create(); | |
| try | |
| { | |
| refBuilder->add_from_file(filename); | |
| } | |
| catch(const Glib::FileError& ex) | |
| { | |
| std::cerr << "FileError: " << ex.what() << std::endl; | |
| return Glib::RefPtr<Gtk::Builder>(); | |
| } | |
| catch(const Glib::MarkupError& ex) | |
| { | |
| std::cerr << "MarkupError: " << ex.what() << std::endl; | |
| return Glib::RefPtr<Gtk::Builder>(); | |
| } | |
| catch(const Gtk::BuilderError& ex) | |
| { | |
| std::cerr << "BuilderError: " << ex.what() << std::endl; | |
| return Glib::RefPtr<Gtk::Builder>(); | |
| } | |
| return refBuilder; | |
| } | |
| /** test_my_label.glade | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <!-- Generated with glade 3.22.2 --> | |
| <interface> | |
| <requires lib="gtk+" version="3.20"/> | |
| <object class="gtkmm__CustomObject_my_label" id="widget_mylabel"> | |
| <property name="visible">True</property> | |
| <property name="can_focus">False</property> | |
| <property name="label" translatable="yes">A long text</property> | |
| <property name="my_max_chars">5</property> | |
| </object> | |
| </interface> | |
| **/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?xml version="1.0" encoding="UTF-8"?> | |
| <!-- Generated with glade 3.22.2 --> | |
| <interface> | |
| <requires lib="gtk+" version="3.20"/> | |
| <object class="gtkmm__CustomObject_my_label" id="widget_mylabel"> | |
| <property name="visible">True</property> | |
| <property name="can_focus">False</property> | |
| <property name="label" translatable="yes">A long text</property> | |
| <property name="my_max_chars">5</property> | |
| </object> | |
| </interface> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment