Python version
This commit is contained in:
parent
1d2e4c0bf6
commit
c93aa6e170
28
README.md
Normal file
28
README.md
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# glade-test
|
||||||
|
|
||||||
|
Some experimentation with GTK+ 3.0 / Glade GUIs in Go and Python, particularly
|
||||||
|
for a mobile app UI with multiple screens.
|
||||||
|
|
||||||
|
![Screenshot](screenshot.png)
|
||||||
|
|
||||||
|
Some features exercised:
|
||||||
|
|
||||||
|
* A single-window app with multiple screens ("About" button slides to the
|
||||||
|
About screen, Menu->Home button transitions back to main screen, etc.)
|
||||||
|
* Dynamically added buttons to a Gtk.Box defined in the Glade file. The buttons
|
||||||
|
click into a "Detail" screen updated with the label of the button clicked.
|
||||||
|
* Menu->Open builds a dynamic Open File dialog.
|
||||||
|
* Menu->New shows a custom New File dialog defined in the Glade file.
|
||||||
|
|
||||||
|
## Python Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies (Fedora)
|
||||||
|
sudo dnf install gobject-introspection-devel
|
||||||
|
|
||||||
|
# Python dependencies
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# Run it
|
||||||
|
python main.py
|
||||||
|
```
|
109
main.py
Normal file
109
main.py
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
from gi.repository import Gtk, GObject, GLib
|
||||||
|
|
||||||
|
class Main:
|
||||||
|
def __init__(self):
|
||||||
|
glade_file = "ui/app.glade"
|
||||||
|
self.builder = Gtk.Builder()
|
||||||
|
self.builder.add_from_file(glade_file)
|
||||||
|
self.builder.connect_signals(self)
|
||||||
|
|
||||||
|
self.mw = self.builder.get_object("main_window")
|
||||||
|
self.stack = self.builder.get_object("mw_stack")
|
||||||
|
self.stack_main = self.builder.get_object("box_main")
|
||||||
|
self.stack_about = self.builder.get_object("box_about")
|
||||||
|
self.stack_detail = self.builder.get_object("box_detail")
|
||||||
|
self.detail_header = self.builder.get_object("box_detail_header")
|
||||||
|
self.dlg_new = self.builder.get_object("dlg_new_file")
|
||||||
|
self.listbox = self.builder.get_object("mw_list")
|
||||||
|
self.dyn_btn_box = self.builder.get_object("dyn_btn_box")
|
||||||
|
|
||||||
|
for row in ["First Button", "Second", "Third"]:
|
||||||
|
self.add_button(row)
|
||||||
|
|
||||||
|
self.mw.show_all()
|
||||||
|
|
||||||
|
Gtk.main()
|
||||||
|
|
||||||
|
def add_button(self, label):
|
||||||
|
btn = Gtk.Button.new_with_label(label)
|
||||||
|
btn.connect("clicked", lambda *args: self.goto_detail_screen(label))
|
||||||
|
self.dyn_btn_box.pack_start(btn, expand=False, fill=True, padding=0)
|
||||||
|
|
||||||
|
def goto_detail_screen(self, label):
|
||||||
|
self.detail_header.set_text("Detail: " + label)
|
||||||
|
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
|
||||||
|
self.stack.set_visible_child(self.stack_detail)
|
||||||
|
|
||||||
|
### methods below are Glade signal handlers
|
||||||
|
|
||||||
|
def on_main_window_destroy(self, *args):
|
||||||
|
Gtk.main_quit()
|
||||||
|
|
||||||
|
def on_menu_new_activate(self, *args):
|
||||||
|
print("new clicked")
|
||||||
|
self.dlg_new.show()
|
||||||
|
|
||||||
|
def on_menu_open_activate(self, *args):
|
||||||
|
print("open clicked")
|
||||||
|
|
||||||
|
print(dir(Gtk.FileChooserDialog))
|
||||||
|
dialog = Gtk.FileChooserDialog(
|
||||||
|
"Please choose a file",
|
||||||
|
self.mw,
|
||||||
|
Gtk.FileChooserAction.OPEN,
|
||||||
|
(
|
||||||
|
Gtk.STOCK_CANCEL,
|
||||||
|
Gtk.ResponseType.CANCEL,
|
||||||
|
Gtk.STOCK_OPEN,
|
||||||
|
Gtk.ResponseType.OK,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
filter = Gtk.FileFilter()
|
||||||
|
filter.set_name("JPEG images")
|
||||||
|
filter.add_mime_type("image/jpeg")
|
||||||
|
dialog.add_filter(filter)
|
||||||
|
|
||||||
|
filter_any = Gtk.FileFilter()
|
||||||
|
filter_any.set_name("Any files")
|
||||||
|
filter_any.add_pattern("*")
|
||||||
|
dialog.add_filter(filter_any)
|
||||||
|
|
||||||
|
resp = dialog.run()
|
||||||
|
if resp == Gtk.ResponseType.OK:
|
||||||
|
print("file chosen:", dialog.get_filename())
|
||||||
|
elif resp == Gtk.ResponseType.CANCEL:
|
||||||
|
print("canceled!")
|
||||||
|
|
||||||
|
dialog.destroy()
|
||||||
|
|
||||||
|
def on_menu_quit_activate(self, *args):
|
||||||
|
self.mw.destroy()
|
||||||
|
|
||||||
|
def on_btn_about_clicked(self, *args):
|
||||||
|
print("about clicked")
|
||||||
|
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
|
||||||
|
self.stack.set_visible_child(self.stack_about)
|
||||||
|
|
||||||
|
def on_btn_about_back_clicked(self, *args):
|
||||||
|
print("about back")
|
||||||
|
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
|
||||||
|
self.stack.set_visible_child(self.stack_main)
|
||||||
|
|
||||||
|
def on_btn_detail_back_clicked(self, *args):
|
||||||
|
self.on_btn_about_back_clicked(*args)
|
||||||
|
|
||||||
|
def on_menu_save_activate(self, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_menu_home_activate(self, *args):
|
||||||
|
self.on_btn_about_back_clicked(*args)
|
||||||
|
|
||||||
|
def on_new_file_selected(self, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
Main()
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pycairo
|
||||||
|
PyGObject
|
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Loading…
Reference in New Issue
Block a user