diff --git a/README.md b/README.md index eb09373..919e7ef 100644 --- a/README.md +++ b/README.md @@ -963,6 +963,95 @@ Once you make a .desktop file, in it set the icon field to your app id: `Icon=co **A:** In modern desktop Linux the idea is you don't. Wayland provides no mechanism for a client program to set an icon. How it works is the Wayland client sends your application ID to the window manager, its your window manager which then takes responsibility for picking the icon itself. This is done by referencing the .desktop file, where that application ID corresponds to the name of the desktop file. +## UI from XML + +It may be faster to mock up a UI in a graghical designer such as [Cambalache](https://flathub.org/apps/ar.xjuan.Cambalache). This will a give you a .ui file which your +GTK application can use to generate its UI. + +In Cambalache try make a window, add some layouts, and a button. Its up to you. Make sure to set an object id for objects you want to reference in your code, +including the main window. When you click export it will generate a .ui XML file. + +![Cambalache](cam.png) + +For my design I get the XML: + +```xml + + + + + + + 200 + 400 + UI XML Test + + + + + 5 + 5 + 5 + 5 + vertical + + + start + True + Test button + + + + + + + + +``` + +Then we can write our app in Python and load the UI using a [Builder](https://docs.gtk.org/gtk4/class.Builder.html). + +```python +import sys +import gi +gi.require_version('Gtk', '4.0') +gi.require_version('Adw', '1') +from gi.repository import Gtk, Adw + +class MyApp(Adw.Application): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.connect('activate', self.on_activate) + + def on_activate(self, app): + # Create a Builder + builder = Gtk.Builder() + builder.add_from_file("test.ui") + + # Obtain the button widget and connect it to a function + button = builder.get_object("button1") + button.connect("clicked", self.hello) + + # Obtain and show the main window + self.win = builder.get_object("main_window") + self.win.set_application(self) # Application will close once it no longer has active windows attached to it + self.win.present() + + def hello(self, button): + print("Hello") + +app = MyApp(application_id="com.example.GtkApplication") +app.run(sys.argv) + +``` + +So in this method we simply obtain the objects defined by our XML using `builder.get_object()` + +In the above example I get the button I created and connect it to a function. + +***todo:*** using resoure files + + ## Todo... Text box: [Entry](https://docs.gtk.org/gtk4/class.Entry.html) @@ -971,8 +1060,6 @@ Number changer: [SpinButton](https://docs.gtk.org/gtk4/class.SpinButton.html) Picture. -UI from XML. - Custom Styles. diff --git a/cam.png b/cam.png new file mode 100644 index 0000000..1259f5c Binary files /dev/null and b/cam.png differ diff --git a/part3.py b/part3.py new file mode 100644 index 0000000..a7dcfbe --- /dev/null +++ b/part3.py @@ -0,0 +1,30 @@ +import sys +import gi +gi.require_version('Gtk', '4.0') +gi.require_version('Adw', '1') +from gi.repository import Gtk, Adw + +class MyApp(Adw.Application): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.connect('activate', self.on_activate) + + def on_activate(self, app): + # Create a Builder + builder = Gtk.Builder() + builder.add_from_file("test.ui") + + # Obtain the button widget and connect it to a function + button = builder.get_object("button1") + button.connect("clicked", self.hello) + + # Obtain and show the main window + self.win = builder.get_object("main_window") + self.win.set_application(self) # Application will close once it no longer has active windows attached to it + self.win.present() + + def hello(self, button): + print("Hello") + +app = MyApp(application_id="com.example.GtkApplication") +app.run(sys.argv) \ No newline at end of file diff --git a/test.ui b/test.ui new file mode 100644 index 0000000..ae1a18b --- /dev/null +++ b/test.ui @@ -0,0 +1,31 @@ + + + + + + + 200 + 400 + UI XML Test + + + + + 5 + 5 + 5 + 5 + vertical + + + start + True + Test button + + + + + + + +