init: vm manager list view
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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()
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user