init: vm manager list view

This commit is contained in:
Johannes Kirschbauer 2023-11-28 10:23:49 +01:00
parent f7422e2a35
commit ebe411d50d
Signed by: hsjobeki
SSH Key Fingerprint: SHA256:vX3utDqig7Ph5L0JPv87ZTPb/w7cMzREKVZzzLFg9qU
4 changed files with 52 additions and 193 deletions

View File

@ -41,6 +41,8 @@ cd ..
make
```
- The use the GTK Builder instead of templates.
## Look into virt-manager it uses python + spice-gtk
Look into `virtManager/details/viewers.py` to see how spice-gtk is being used
@ -68,6 +70,7 @@ import the glade file through GTK template
- Also look into [PyGObject](https://pygobject.readthedocs.io/en/latest/guide/gtk_template.html) to know more about threading and async etc.
- [GI Python API](https://lazka.github.io/pgi-docs/#Gtk-3.0)
- https://developer.gnome.org/documentation/tutorials/application.html
- [GTK3 Python] https://github.com/sam-m888/python-gtk3-tutorial/tree/master
## My gripes with GTK

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<template class="main-window" parent="GtkApplicationWindow">
<property name="can-focus">False</property>
<signal name="destroy" handler="onDestroy" swapped="no"/>
<child>
<object class="GtkFixed">
<property name="name">asdasd</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkButton" id="help_button">
<property name="label" translatable="yes">May I help you?</property>
<property name="name">asdasd</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="image-position">top</property>
<signal name="clicked" handler="onButtonPressed" swapped="no"/>
</object>
<packing>
<property name="x">21</property>
<property name="y">21</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="coffee_label">
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Get me some coffe! </property>
<property name="width-chars">0</property>
</object>
<packing>
<property name="x">178</property>
<property name="y">120</property>
</packing>
</child>
<child>
<object class="GtkButton" id="next_button">
<property name="label" translatable="yes">Next</property>
<property name="width-request">79</property>
<property name="height-request">39</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="onNextButtonPressed" swapped="no"/>
</object>
<packing>
<property name="x">355</property>
<property name="y">190</property>
</packing>
</child>
<style>
<class name="asdasd"/>
</style>
</object>
</child>
</template>
</interface>

View File

@ -8,98 +8,63 @@ import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gio, Gtk
glade_dir = Path(__file__).parent
vms = [
("clan://clan.lol", True, "/home/user/my-clan"),
("clan://lassul.lol", False, "/home/user/my-clan"),
("clan://mic.lol", False, "/home/user/my-clan"),
]
class MainWindow(Gtk.Window):
def __init__(self) -> None:
super().__init__()
# Initialize the main window
self.set_title("Clan VM Manager")
self.connect("delete-event", Gtk.main_quit)
# Some styling
self.set_border_width(10)
# self.set_default_size(500,300)
# Add a notebook layout
# https://python-gtk-3-tutorial.readthedocs.io/en/latest/layout.html#notebook
self.notebook = Gtk.Notebook()
self.add(self.notebook)
vms_store = Gtk.ListStore(str,bool,str)
for vm in vms:
vms_store.append(list(vm))
self.machine_tree_view = Gtk.TreeView(vms_store)
for idx, title in enumerate(["Url", "Autostart", "Path"]):
renderer = Gtk.CellRendererText()
col = Gtk.TreeViewColumn(title, renderer, text=idx)
col.set_sort_column_id(idx)
self.machine_tree_view.append_column(col)
#
# 1. our .glade file (may contain paths)
#
@Gtk.Template.from_file(glade_dir / "app.glade")
class AppWindow(Gtk.ApplicationWindow):
#
# 2. the GtkApplicationWindow class
#
__gtype_name__ = "main-window"
#
# 3. the Button name we saved above
#
help_button: Gtk.Button = Gtk.Template.Child()
next_button: Gtk.Button = Gtk.Template.Child()
@Gtk.Template.Callback()
def onDestroy(self, _):
Gio.Application.quit(self.get_application())
#
# 4. the signal handler name we saved above
#
@Gtk.Template.Callback()
def onButtonPressed(self, widget, **_kwargs):
assert self.help_button == widget
print(widget.get_label())
@Gtk.Template.Callback()
def onNextButtonPressed(self, widget, **_kwargs):
assert self.next_button == widget
# Hide the first window
self.hide()
# Show the second window
self.get_application().window2.show_all()
self.machine_page = Gtk.Box()
self.machine_page.set_border_width(10)
self.machine_page.add(self.machine_tree_view)
self.notebook.append_page(self.machine_page, Gtk.Label(label="Overview"))
# Decorate the second window class with the template
@Gtk.Template.from_file(glade_dir / "second.glade")
class SecondWindow(Gtk.ApplicationWindow):
#
# the GtkApplicationWindow class
#
__gtype_name__ = "second-window"
# import the button from the template with name 'back_button'
back_button: Gtk.Button = Gtk.Template.Child()
@Gtk.Template.Callback()
def onDestroy(self, _):
Gio.Application.quit(self.get_application())
#
# 'onBackButtonPressed' is the name of the signal handler we saved in glade
#
@Gtk.Template.Callback()
def onBackButtonPressed(self, widget, **_kwargs):
assert self.back_button == widget
# Hide the second window
self.hide()
# Show the first window
self.get_application().window1.show_all()
class Application(Gtk.Application):
def __init__(self, *args, **kwargs):
super().__init__(
*args,
application_id="clan.lol.Gtk1",
flags=Gio.ApplicationFlags.FLAGS_NONE,
**kwargs,
self.join_page = Gtk.Box()
self.join_page.set_border_width(10)
self.join_page.add(Gtk.Label(label="Add/Join another clan"))
self.notebook.append_page(
self.join_page, Gtk.Label(label="Add/Join")
)
self.window = None
def do_activate(self):
# Load the first window from the template
self.window1 = AppWindow(application=self)
# Add the first window to the application
self.add_window(self.window1)
# Show the first window
self.window1.show_all()
# Load the second window from the template
self.window2 = SecondWindow(application=self)
# Add the second window to the application
self.add_window(self.window2)
# Must be called AFTER all components were added
self.show_all()
def on_button_click(self,widget):
print(f"{self} {widget}")
def start_app(args: argparse.Namespace) -> None:
app = Application()
app.run()
MainWindow()
Gtk.main()

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<template class="second-window" parent="GtkApplicationWindow">
<property name="can-focus">False</property>
<signal name="destroy" handler="onDestroy" swapped="no"/>
<child>
<object class="GtkFixed">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkButton" id="back_button">
<property name="label" translatable="yes">go back</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="onBackButtonPressed" swapped="no"/>
</object>
<packing>
<property name="x">348</property>
<property name="y">201</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">button</property>
<property name="width-request">100</property>
<property name="height-request">80</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="x">71</property>
<property name="y">53</property>
</packing>
</child>
</object>
</child>
</template>
</interface>