mirror of
https://github.com/Apress/foundations-of-pygtk-development.git
synced 2025-07-21 03:41:10 +02:00
Initial commit
This commit is contained in:
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
BIN
9781484241783.jpg
Normal file
BIN
9781484241783.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
31
App_and_AppWindow/Application1.py
Normal file
31
App_and_AppWindow/Application1.py
Normal file
@@ -0,0 +1,31 @@
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
|
||||
**kwargs)
|
||||
self.window = None
|
||||
self.add_main_option("test", ord("t"), GLib.OptionFlags.NONE,
|
||||
GLib.OptionArg.NONE, "Command line test", None)
|
||||
|
||||
def do_startup(self):
|
||||
Gtk.Application.do_startup(self)
|
||||
action = Gio.SimpleAction.new("quit", None)
|
||||
action.connect("activate", self.on_quit)
|
||||
self.add_action(action)
|
||||
|
||||
def do_activate(self):
|
||||
# We only allow a single window and raise any existing ones
|
||||
if not self.window:
|
||||
# Windows are associated with the application
|
||||
# when the last one is closed the application shuts down
|
||||
self.window = AppWindow(application=self, title="Main Window")
|
||||
self.window.present()
|
||||
|
||||
def do_command_line(self, command_line):
|
||||
options = command_line.get_options_dict()
|
||||
if options.contains("test"):
|
||||
# This is printed on the main instance
|
||||
print("Test argument recieved")
|
||||
self.activate()
|
||||
return 0
|
133
App_and_AppWindow/Application2.py
Normal file
133
App_and_AppWindow/Application2.py
Normal file
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import GLib, Gio, Gtk
|
||||
|
||||
# This would typically be its own file
|
||||
MENU_XML="""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="app-menu">
|
||||
<section>
|
||||
<attribute name="label" translatable="yes">Change label</attribute>
|
||||
<item>
|
||||
<attribute name="action">win.change_label</attribute>
|
||||
<attribute name="target">String 1</attribute>
|
||||
<attribute name="label" translatable="yes">String 1</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">win.change_label</attribute>
|
||||
<attribute name="target">String 2</attribute>
|
||||
<attribute name="label" translatable="yes">String 2</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">win.change_label</attribute>
|
||||
<attribute name="target">String 3</attribute>
|
||||
<attribute name="label" translatable="yes">String 3</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">win.maximize</attribute>
|
||||
<attribute name="label" translatable="yes">Maximize</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">app.about</attribute>
|
||||
<attribute name="label" translatable="yes">_About</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">app.quit</attribute>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="accel"><Primary>q</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
"""
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# This will be in the windows group and have the "win" prefix
|
||||
max_action = Gio.SimpleAction.new_stateful("maximize", None,
|
||||
GLib.Variant.new_boolean(False))
|
||||
max_action.connect("change-state", self.on_maximize_toggle)
|
||||
self.add_action(max_action)
|
||||
# Keep it in sync with the actual state
|
||||
self.connect("notify::is-maximized",
|
||||
lambda obj, pspec: max_action.set_state(
|
||||
GLib.Variant.new_boolean(obj.props.is_maximized)))
|
||||
lbl_variant = GLib.Variant.new_string("String 1")
|
||||
lbl_action = Gio.SimpleAction.new_stateful("change_label",
|
||||
lbl_variant.get_type(),
|
||||
lbl_variant)
|
||||
lbl_action.connect("change-state", self.on_change_label_state)
|
||||
self.add_action(lbl_action)
|
||||
self.label = Gtk.Label(label=lbl_variant.get_string(),
|
||||
margin=30)
|
||||
self.add(self.label)
|
||||
|
||||
def on_change_label_state(self, action, value):
|
||||
action.set_state(value)
|
||||
self.label.set_text(value.get_string())
|
||||
|
||||
def on_maximize_toggle(self, action, value):
|
||||
action.set_state(value)
|
||||
if value.get_boolean():
|
||||
self.maximize()
|
||||
else:
|
||||
self.unmaximize()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE,
|
||||
**kwargs)
|
||||
self.window = None
|
||||
self.add_main_option("test", ord("t"), GLib.OptionFlags.NONE,
|
||||
GLib.OptionArg.NONE, "Command line test", None)
|
||||
|
||||
def do_startup(self):
|
||||
Gtk.Application.do_startup(self)
|
||||
action = Gio.SimpleAction.new("about", None)
|
||||
action.connect("activate", self.on_about)
|
||||
self.add_action(action)
|
||||
action = Gio.SimpleAction.new("quit", None)
|
||||
action.connect("activate", self.on_quit)
|
||||
self.add_action(action)
|
||||
builder = Gtk.Builder.new_from_string(MENU_XML, -1)
|
||||
self.set_app_menu(builder.get_object("app-menu"))
|
||||
|
||||
def do_activate(self):
|
||||
# We only allow a single window and raise any existing ones
|
||||
if not self.window:
|
||||
# Windows are associated with the application
|
||||
# when the last one is closed the application shuts down
|
||||
self.window = AppWindow(application=self, title="Main Window")
|
||||
self.window.present()
|
||||
|
||||
def do_command_line(self, command_line):
|
||||
options = command_line.get_options_dict()
|
||||
if options.contains("test"):
|
||||
# This is printed on the main instance
|
||||
print("Test argument recieved")
|
||||
self.activate()
|
||||
return 0
|
||||
|
||||
def on_about(self, action, param):
|
||||
about_dialog = Gtk.AboutDialog(transient_for=self.window, modal=True)
|
||||
about_dialog.present()
|
||||
|
||||
def on_quit(self, action, param):
|
||||
self.quit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
49
Basic_Widgets/CheckButtons.py
Normal file
49
Basic_Widgets/CheckButtons.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
check1 = Gtk.CheckButton.new_with_label("I am the main option.")
|
||||
check2 = Gtk.CheckButton.new_with_label("I rely on the other guy.")
|
||||
check2.set_sensitive(False)
|
||||
check1.connect("toggled", self.on_button_checked, check2)
|
||||
closebutton = Gtk.Button.new_with_mnemonic("_Close")
|
||||
closebutton.connect("clicked", self.on_button_close_clicked)
|
||||
vbox = Gtk.Box.new(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(check1, False, True, 0)
|
||||
vbox.pack_start(check2, False, True, 0)
|
||||
vbox.pack_start(closebutton, False, True, 0)
|
||||
self.add(vbox)
|
||||
|
||||
def on_button_checked(self, check1, check2):
|
||||
if check1.get_active():
|
||||
check2.set_sensitive(True);
|
||||
else:
|
||||
check2.set_sensitive(False)
|
||||
|
||||
def on_button_close_clicked(self, button):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Check Buttons")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
70
Basic_Widgets/Exercise_1.py
Normal file
70
Basic_Widgets/Exercise_1.py
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
|
||||
rnm = Gtk.Button.new_with_label("Apply")
|
||||
name = Gtk.Entry.new()
|
||||
rnm.set_sensitive(False)
|
||||
name.set_sensitive(False)
|
||||
|
||||
file = Gtk.FileChooserButton("Choose File", Gtk.FileChooserAction.OPEN)
|
||||
file.set_current_folder(str(Path.home()))
|
||||
|
||||
file.connect("selection-changed", self.on_file_changed, file, rnm,
|
||||
name)
|
||||
rnm.connect("clicked", self.on_rename_clicked, file, rnm, name)
|
||||
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||
hbox.pack_start(name, True, True, 0)
|
||||
hbox.pack_start(rnm, False, True, 0)
|
||||
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(file, False, True, 0)
|
||||
vbox.pack_start(hbox, False, True, 0)
|
||||
|
||||
self.add(vbox)
|
||||
|
||||
|
||||
def on_file_changed(self, chooser, file, rnm, name):
|
||||
fn = file.get_filename()
|
||||
mode = os.access(fn, os.W_OK)
|
||||
|
||||
rnm.set_sensitive(mode)
|
||||
name.set_sensitive(mode)
|
||||
|
||||
def on_rename_clicked(self, chooser, file, rnm, name):
|
||||
old = file.get_filename()
|
||||
location = file.get_current_folder()
|
||||
new = location + "/" + name.get_text()
|
||||
|
||||
os.rename(old, new)
|
||||
rnm.set_sensitive(False)
|
||||
name.set_sensitive(False)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="File Chooser Button Exercise")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
65
Basic_Widgets/Exercise_2.py
Normal file
65
Basic_Widgets/Exercise_2.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
|
||||
adj1 = Gtk.Adjustment.new(0.5, 0.0, 1.0, 0.01, 0.02, 0.02)
|
||||
adj2 = Gtk.Adjustment.new(0.5, 0.0, 1.02, 0.01, 0.02, 0.02)
|
||||
|
||||
spin = Gtk.SpinButton.new(adj1, 0.01, 2)
|
||||
scale = Gtk.Scale.new(Gtk.Orientation.HORIZONTAL, adj2)
|
||||
check = Gtk.CheckButton.new_with_label("Synchronize Spin and Scale")
|
||||
|
||||
check.set_active(True)
|
||||
scale.set_digits(2)
|
||||
scale.set_value_pos(Gtk.PositionType.RIGHT)
|
||||
|
||||
spin.connect("value_changed", self.on_spin_value_changed, spin, scale, check)
|
||||
scale.connect("value_changed", self.on_scale_value_changed, spin, scale, check)
|
||||
|
||||
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5);
|
||||
vbox.pack_start(spin, False, True, 0)
|
||||
vbox.pack_start(scale, False, True, 0);
|
||||
vbox.pack_start(check, False, True, 0);
|
||||
|
||||
self.add(vbox)
|
||||
|
||||
|
||||
def on_spin_value_changed(self, widget, spin, scale, check):
|
||||
val1 = spin.get_value()
|
||||
val2 = scale.get_value()
|
||||
|
||||
if (check.get_active() and val1 != val2):
|
||||
if isinstance(widget, Gtk.SpinButton):
|
||||
scale.set_value(val1)
|
||||
else:
|
||||
spin.set_value(val2)
|
||||
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Exercise 2")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
45
Basic_Widgets/GtkColorButtonWidget.py
Normal file
45
Basic_Widgets/GtkColorButtonWidget.py
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
color = Gdk.RGBA(red=0, green=.33, blue=.66, alpha=1.0)
|
||||
color = Gdk.RGBA.to_color(color)
|
||||
button = Gtk.ColorButton.new_with_color(color)
|
||||
button.set_title("Select a Color!")
|
||||
label = Gtk.Label("Look at my color!")
|
||||
label.modify_fg(Gtk.StateType.NORMAL, color)
|
||||
button.connect("color_set", self.on_color_changed, label)
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||
hbox.pack_start(button, False, False, 5)
|
||||
hbox.pack_start(label, False, False, 5)
|
||||
self.add(hbox)
|
||||
|
||||
def on_color_changed(self, button, label):
|
||||
color = button.get_color()
|
||||
label.modify_fg(Gtk.StateType.NORMAL, color)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Color Button")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
43
Basic_Widgets/GtkEntry.py
Normal file
43
Basic_Widgets/GtkEntry.py
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
import os
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
prompt_str = "What is the password for " + os.getlogin() + "?"
|
||||
question = Gtk.Label(prompt_str)
|
||||
label = Gtk.Label("Password:")
|
||||
passwd = Gtk.Entry()
|
||||
passwd.set_visibility(False)
|
||||
passwd.set_invisible_char("*")
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||
hbox.pack_start(label, False, False, 5)
|
||||
hbox.pack_start(passwd, False, False, 5)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(question, False, False, 0)
|
||||
vbox.pack_start(hbox, False, False, 0)
|
||||
self.add(vbox)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Password")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
64
Basic_Widgets/GtkFileChooserButtonWidget.py
Normal file
64
Basic_Widgets/GtkFileChooserButtonWidget.py
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
from pathlib import Path
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
label = Gtk.Label("")
|
||||
chooser1 = Gtk.FileChooserButton("Choose a Folder.",
|
||||
Gtk.FileChooserAction.SELECT_FOLDER)
|
||||
chooser2 = Gtk.FileChooserButton("Choose a Folder.",
|
||||
Gtk.FileChooserAction.OPEN)
|
||||
chooser1.connect("selection_changed", self.on_folder_changed,
|
||||
chooser2)
|
||||
chooser2.connect("selection_changed", self.on_file_changed, label)
|
||||
chooser1.set_current_folder(str(Path.home()))
|
||||
chooser2.set_current_folder(str(Path.home()))
|
||||
filter1 = Gtk.FileFilter()
|
||||
filter2 = Gtk.FileFilter()
|
||||
filter1.set_name("Image Files")
|
||||
filter2.set_name("All Files")
|
||||
filter1.add_pattern("*.png")
|
||||
filter1.add_pattern("*.jpg")
|
||||
filter1.add_pattern("*.gif")
|
||||
filter2.add_pattern("*")
|
||||
chooser2.add_filter(filter1)
|
||||
chooser2.add_filter(filter2)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(chooser1, False, False, 0)
|
||||
vbox.pack_start(chooser2, False, False, 0)
|
||||
vbox.pack_start(label, False, False, 0)
|
||||
self.add(vbox)
|
||||
self.set_size_request(240, -1)
|
||||
|
||||
def on_folder_changed(self, chooser1, chooser2):
|
||||
folder = chooser1.get_filename()
|
||||
chooser2.set_current_folder(folder)
|
||||
|
||||
def on_file_changed(self, chooser2, label):
|
||||
file = chooser2.get_filename()
|
||||
label.set_text(file)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="File Chooser Button")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
47
Basic_Widgets/GtkFontButtonWidget.py
Normal file
47
Basic_Widgets/GtkFontButtonWidget.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Pango
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
label = Gtk.Label("Look at the font!")
|
||||
initial_font = Pango.font_description_from_string("Sans Bold 12")
|
||||
label.modify_font(initial_font)
|
||||
button = Gtk.FontButton.new_with_font("Sans Bold 12")
|
||||
button.set_title("Choose a Font")
|
||||
button.connect("font_set", self.on_font_changed, label)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(button, False, False, 0)
|
||||
vbox.pack_start(label, False, False, 0)
|
||||
self.add(vbox)
|
||||
|
||||
def on_font_changed(self, button, label):
|
||||
font = button.get_font()
|
||||
desc = Pango.font_description_from_string(font)
|
||||
buffer = "Font: " + font
|
||||
label.set_text(buffer)
|
||||
label.modify_font(desc)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Font Button")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
42
Basic_Widgets/GtkScaleWidgets.py
Normal file
42
Basic_Widgets/GtkScaleWidgets.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, -1)
|
||||
scale_int = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL,
|
||||
0.0, 10.0, 1.0)
|
||||
scale_float = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL,
|
||||
0.0, 1.0, 0.1)
|
||||
scale_int.set_digits(0)
|
||||
scale_float.set_digits(1)
|
||||
scale_int.set_value_pos(Gtk.PositionType.RIGHT)
|
||||
scale_float.set_value_pos(Gtk.PositionType.LEFT)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(scale_int, False, False, 5)
|
||||
vbox.pack_start(scale_float, False, False, 5)
|
||||
self.add(vbox)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Scales")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
45
Basic_Widgets/GtkSpinButtons.py
Normal file
45
Basic_Widgets/GtkSpinButtons.py
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
integer = Gtk.Adjustment(5.0, 0.0, 10.0, 1.0, 2.0, 2.0)
|
||||
float_pt = Gtk.Adjustment(5.0, 0.0, 1.0, 0.1, 0.5, 0.5)
|
||||
spin_int = Gtk.SpinButton()
|
||||
spin_int.set_adjustment(integer)
|
||||
spin_int.set_increments(1.0, 0)
|
||||
spin_int.set_digits(0)
|
||||
spin_float = Gtk.SpinButton()
|
||||
spin_float.set_adjustment(float_pt)
|
||||
spin_float.set_increments(0.1, 0)
|
||||
spin_float.set_digits(1)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(spin_int, False, False, 5)
|
||||
vbox.pack_start(spin_float, False, False, 5)
|
||||
self.add(vbox)
|
||||
self.set_size_request(180, 100)
|
||||
self.show_all()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Spin Buttons")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
47
Basic_Widgets/LookAlike_Stock_Button.py
Normal file
47
Basic_Widgets/LookAlike_Stock_Button.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
button = Gtk.Button.new()
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||
icon_theme = Gtk.IconTheme.get_default()
|
||||
icon = icon_theme.load_icon("window-close", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
image = Gtk.Image.new_from_pixbuf(icon)
|
||||
hbox.add(image)
|
||||
label = Gtk.Label.new_with_mnemonic("_Close")
|
||||
hbox.add(label)
|
||||
hbox.set_homogeneous(True)
|
||||
button.add(hbox)
|
||||
button.connect("clicked", self.on_button_clicked)
|
||||
button.set_relief(Gtk.ReliefStyle.NORMAL)
|
||||
self.add(button)
|
||||
self.set_size_request(230, 100)
|
||||
|
||||
def on_button_clicked(self, param):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Look-alike Stock Item")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
40
Basic_Widgets/RadioButtons.py
Normal file
40
Basic_Widgets/RadioButtons.py
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
radio1 = Gtk.RadioButton.new_with_label(None, "I want to be clicked!")
|
||||
radio2 = Gtk.RadioButton.new_with_label_from_widget(radio1, "Click me instead!")
|
||||
radio3 = Gtk.RadioButton.new_with_label_from_widget(radio1, "No! Click me!")
|
||||
radio4 = Gtk.RadioButton.new_with_label_from_widget(radio3, "No! Click me instead!")
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(radio1, False, False, 0)
|
||||
vbox.pack_start(radio2, False, False, 0)
|
||||
vbox.pack_start(radio3, False, False, 0)
|
||||
vbox.pack_start(radio4, False, False, 0)
|
||||
self.add(vbox)
|
||||
self.show_all()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Radio Buttons")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
43
Basic_Widgets/ToggleButtons.py
Normal file
43
Basic_Widgets/ToggleButtons.py
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
vbox = Gtk.Box.new(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
toggle1 = Gtk.ToggleButton.new_with_mnemonic("_Deactivate the other one!")
|
||||
toggle2 = Gtk.ToggleButton.new_with_mnemonic("_No! Deactivate that one!")
|
||||
toggle1.connect("toggled", self.on_button_toggled, toggle2)
|
||||
toggle2.connect("toggled", self.on_button_toggled, toggle1)
|
||||
vbox.pack_start(toggle1, True, True, 1)
|
||||
vbox.pack_start(toggle2, True, True, 1)
|
||||
self.add(vbox)
|
||||
|
||||
def on_button_toggled(self, toggle, other_toggle):
|
||||
if (Gtk.ToggleButton.get_active(toggle)):
|
||||
other_toggle.set_sensitive(False)
|
||||
else:
|
||||
other_toggle.set_sensitive(True)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Toggle Buttons")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
47
Containers/Adding_Events_To_GtkLabel.py
Normal file
47
Containers/Adding_Events_To_GtkLabel.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, 50)
|
||||
eventbox = Gtk.EventBox.new()
|
||||
label = Gtk.Label.new("Double-Click Me!")
|
||||
eventbox.set_above_child(False)
|
||||
eventbox.connect("button_press_event", self.on_button_pressed, label)
|
||||
eventbox.add(label)
|
||||
self.add(eventbox)
|
||||
eventbox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
|
||||
eventbox.realize()
|
||||
|
||||
def on_button_pressed(self, eventbox, event, label):
|
||||
if event.type == Gdk.EventType._2BUTTON_PRESS:
|
||||
text = label.get_text()
|
||||
if text[0] == 'D':
|
||||
label.set_text("I Was Double-Clicked!")
|
||||
else:
|
||||
label.set_text("Double-Click Me Again!")
|
||||
return False
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Hello World!")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
40
Containers/Container_With_Multiple_Pages.py
Normal file
40
Containers/Container_With_Multiple_Pages.py
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, 100)
|
||||
notebook = Gtk.Notebook.new()
|
||||
label1 = Gtk.Label.new("Page 1")
|
||||
label2 = Gtk.Label.new("Page 2")
|
||||
child1 = Gtk.Label.new("Go to page 2 to find the answer.")
|
||||
child2 = Gtk.Label.new("Go to page 1 to find the answer.")
|
||||
notebook.append_page(child1, label1)
|
||||
notebook.append_page(child2, label2)
|
||||
|
||||
notebook.set_tab_pos(Gtk.PositionType.BOTTOM)
|
||||
self.add(notebook)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Notebook")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
79
Containers/Exercise_1.py
Normal file
79
Containers/Exercise_1.py
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, 150)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
self.add(vbox)
|
||||
|
||||
notebook = Gtk.Notebook.new()
|
||||
notebook.set_tab_pos(Gtk.PositionType.BOTTOM)
|
||||
vbox.pack_start(notebook, False, False, 5)
|
||||
|
||||
label1 = Gtk.Label.new("Page 1")
|
||||
label2 = Gtk.Label.new("Page 2")
|
||||
label3 = Gtk.Label.new("Page 3")
|
||||
label4 = Gtk.Label.new("Page 4")
|
||||
|
||||
button1 = Gtk.Button.new_with_label("Go to Page 2")
|
||||
button1.connect("clicked", self.on_notebook_button_clicked, notebook)
|
||||
button2 = Gtk.Button.new_with_label("Go to Page 3")
|
||||
button2.connect("clicked", self.on_notebook_button_clicked, notebook)
|
||||
button3 = Gtk.Button.new_with_label("Go to Page 4")
|
||||
button3.connect("clicked", self.on_notebook_button_clicked, notebook)
|
||||
button4 = Gtk.Button.new_with_label("Go to Page 1")
|
||||
button4.connect("clicked", self.on_notebook_button_clicked, notebook)
|
||||
|
||||
page1 = notebook.append_page(button1, label1)
|
||||
page2 = notebook.append_page(button2, label2)
|
||||
page3 = notebook.append_page(button3, label3)
|
||||
page4 = notebook.append_page(button4, label4)
|
||||
|
||||
buttonbox = Gtk.ButtonBox.new(Gtk.Orientation.HORIZONTAL)
|
||||
vbox.pack_start(buttonbox, False, False, 5)
|
||||
button_prev = Gtk.Button.new_with_label("Previous Page")
|
||||
button_prev.connect("clicked", self.on_button_prev_clicked, notebook)
|
||||
button_close = Gtk.Button.new_with_label("Close")
|
||||
button_close.connect("clicked", self.on_button_close_clicked)
|
||||
buttonbox.pack_end(button_prev, False, False, 5)
|
||||
buttonbox.pack_end(button_close, False, False, 5)
|
||||
|
||||
def on_notebook_button_clicked(self, button, notebook):
|
||||
nextpage = notebook.props.page + 1
|
||||
if nextpage == 4:
|
||||
nextpage = 0
|
||||
notebook.set_current_page(nextpage)
|
||||
|
||||
def on_button_prev_clicked(self, button, notebook):
|
||||
nextpage = notebook.props.page - 1
|
||||
if nextpage == -1:
|
||||
nextpage = 3
|
||||
notebook.set_current_page(nextpage)
|
||||
|
||||
def on_button_close_clicked(self, button):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Notebook")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
75
Containers/Exercise_2.py
Normal file
75
Containers/Exercise_2.py
Normal file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, 200)
|
||||
|
||||
notebook = Gtk.Notebook.new()
|
||||
notebook.set_show_tabs(False)
|
||||
|
||||
for i in range(0, 4):
|
||||
label = Gtk.Label.new("Tab")
|
||||
button = Gtk.Button.new_with_mnemonic("_Next Tab")
|
||||
|
||||
expander = Gtk.Expander.new("You Are Viewing Tab %s" % str(i+1))
|
||||
expander.set_expanded(True)
|
||||
expander.add (button)
|
||||
|
||||
notebook.append_page(expander, label)
|
||||
expander.set_border_width(10)
|
||||
|
||||
button.connect("clicked", self.on_notebook_button_clicked, notebook)
|
||||
|
||||
buttonbox = Gtk.ButtonBox.new(Gtk.Orientation.HORIZONTAL)
|
||||
button_prev = Gtk.Button.new_with_label("Previous Page")
|
||||
button_prev.connect("clicked", self.on_button_prev_clicked, notebook)
|
||||
button_close = Gtk.Button.new_with_label("Close")
|
||||
button_close.connect("clicked", self.on_button_close_clicked)
|
||||
buttonbox.pack_end(button_prev, False, False, 5)
|
||||
buttonbox.pack_end(button_close, False, False, 5)
|
||||
|
||||
paned = Gtk.Paned.new(Gtk.Orientation.VERTICAL)
|
||||
paned.pack1(notebook, True, False)
|
||||
paned.pack2(buttonbox, True, False)
|
||||
|
||||
self.add(paned)
|
||||
|
||||
def on_notebook_button_clicked(self, button, notebook):
|
||||
nextpage = notebook.props.page + 1
|
||||
if nextpage == 4:
|
||||
nextpage = 0
|
||||
notebook.set_current_page(nextpage)
|
||||
|
||||
def on_button_prev_clicked(self, button, notebook):
|
||||
nextpage = notebook.props.page - 1
|
||||
if nextpage == -1:
|
||||
nextpage = 3
|
||||
notebook.set_current_page(nextpage)
|
||||
|
||||
def on_button_close_clicked(self, button):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Notebook")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
40
Containers/Grid_Displaying_Name.py
Normal file
40
Containers/Grid_Displaying_Name.py
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(150, 100)
|
||||
grid = Gtk.Grid.new()
|
||||
label1 = Gtk.Label.new("Enter the following information ...")
|
||||
label2 = Gtk.Label.new("Name: ")
|
||||
entry = Gtk.Entry.new()
|
||||
grid.attach(label1, 0, 0, 2, 1)
|
||||
grid.attach(label2, 0, 1, 1, 1)
|
||||
grid.attach(entry, 1, 1, 1, 1)
|
||||
grid.set_row_spacing(5)
|
||||
grid.set_column_spacing(5)
|
||||
self.add(grid)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Tables")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
42
Containers/Horizontal_Paned_With_Buttons.py
Normal file
42
Containers/Horizontal_Paned_With_Buttons.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
hpaned = Gtk.Paned.new(Gtk.Orientation.HORIZONTAL)
|
||||
button1 = Gtk.Button.new_with_label("Resize")
|
||||
button2 = Gtk.Button.new_with_label("Me!")
|
||||
button1.connect("clicked", self.on_button_clicked)
|
||||
button2.connect("clicked", self.on_button_clicked)
|
||||
hpaned.add1(button1)
|
||||
hpaned.add2(button2)
|
||||
self.add(hpaned)
|
||||
self.set_size_request(225, 150)
|
||||
self.show_all()
|
||||
|
||||
def on_button_clicked(self, button):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Panes")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
35
Containers/Showing_And_Hiding_Widgets.py
Normal file
35
Containers/Showing_And_Hiding_Widgets.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, 100)
|
||||
expander = Gtk.Expander.new_with_mnemonic("Click _Me For More!")
|
||||
label = Gtk.Label.new ("Hide me or show me,\nthat is your choice.")
|
||||
expander.add(label)
|
||||
expander.set_expanded(True)
|
||||
self.add(expander)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Hello World!")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
41
Containers/Specifying_Exact_Locations.py
Normal file
41
Containers/Specifying_Exact_Locations.py
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
fixed = Gtk.Fixed.new()
|
||||
button1 = Gtk.Button.new_with_label("Pixel by pixel ...")
|
||||
button2 = Gtk.Button.new_with_label("you choose my fate.")
|
||||
button1.connect("clicked", self.on_button_clicked)
|
||||
button2.connect("clicked", self.on_button_clicked)
|
||||
fixed.put(button1, 0, 0)
|
||||
fixed.put(button2, 22, 35)
|
||||
self.add(fixed)
|
||||
self.show_all()
|
||||
|
||||
def on_button_clicked(self, widget):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Fixed")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
44
Containers/Vertical_Boxes_Specifying_Packing_Parameters.py
Normal file
44
Containers/Vertical_Boxes_Specifying_Packing_Parameters.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
names = ["Andrew", "Joe", "Samantha", "Jonathan"]
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
for name in names:
|
||||
button = Gtk.Button.new_with_label(name)
|
||||
vbox.pack_end(button, False, False, 5)
|
||||
button.connect("clicked", self.on_button_clicked)
|
||||
button.set_relief(Gtk.ReliefStyle.NORMAL)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, -1)
|
||||
self.add(vbox)
|
||||
self.show_all()
|
||||
|
||||
def on_button_clicked(self, widget):
|
||||
self.destroy()
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Boxes")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
44
Containers/Vertical_Boxes_With_Default_Packing.py
Normal file
44
Containers/Vertical_Boxes_With_Default_Packing.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
names = ["Andrew", "Joe", "Samantha", "Jonathan"]
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
for name in names:
|
||||
button = Gtk.Button.new_with_label(name)
|
||||
vbox.pack_start(button, True, True, 0)
|
||||
button.connect("clicked", self.on_button_clicked)
|
||||
button.set_relief(Gtk.ReliefStyle.NORMAL)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, -1)
|
||||
self.add(vbox)
|
||||
self.show_all()
|
||||
|
||||
def on_button_clicked(self, widget):
|
||||
self.destroy()
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Boxes")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
14
Contributing.md
Normal file
14
Contributing.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Contributing to Apress Source Code
|
||||
|
||||
Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers.
|
||||
|
||||
## How to Contribute
|
||||
|
||||
1. Make sure you have a GitHub account.
|
||||
2. Fork the repository for the relevant book.
|
||||
3. Create a new branch on which to make your change, e.g.
|
||||
`git checkout -b my_code_contribution`
|
||||
4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted.
|
||||
5. Submit a pull request.
|
||||
|
||||
Thank you for your contribution!
|
65
Custom_Widgets/Alignment.py
Normal file
65
Custom_Widgets/Alignment.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.resize(300, 100)
|
||||
# create a grid
|
||||
grid1 = Gtk.Grid()
|
||||
grid1.height = 2
|
||||
grid1.width = 2
|
||||
grid1.set_column_homogeneous(True)
|
||||
grid1.set_row_homogeneous(True)
|
||||
self.add(grid1)
|
||||
# build the aligned labels
|
||||
label1 = Gtk.Label('Top left Aligned')
|
||||
label1.can_focus = False
|
||||
label1.set_halign(Gtk.Align.START)
|
||||
label1.set_valign(Gtk.Align.START)
|
||||
grid1.attach(label1, 0, 0, 1, 1)
|
||||
label2 = Gtk.Label('Top right Aligned')
|
||||
label2.can_focus = False
|
||||
label2.set_halign(Gtk.Align.END)
|
||||
label2.set_valign(Gtk.Align.START)
|
||||
grid1.attach(label2, 1, 0, 1, 1)
|
||||
label3 = Gtk.Label('Bottom left Aligned')
|
||||
label3.can_focus = False
|
||||
label3.set_halign(Gtk.Align.START)
|
||||
label3.set_valign(Gtk.Align.END)
|
||||
grid1.attach(label3, 0, 1, 1, 1)
|
||||
label4 = Gtk.Label('Bottom right Aligned')
|
||||
label4.can_focus = False
|
||||
label4.set_halign(Gtk.Align.END)
|
||||
label4.set_valign(Gtk.Align.END)
|
||||
grid1.attach(label4, 1, 1, 1, 1)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
gtk_version = float(str(Gtk.MAJOR_VERSION)+'.'+str(Gtk.MINOR_VERSION))
|
||||
if gtk_version < 3.16:
|
||||
print('There is a bug in versions of GTK older that 3.16.')
|
||||
print('Your version is not new enough to prevent this bug from')
|
||||
print('causing problems in the display of this solution.')
|
||||
exit(0)
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Alignment")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
35
Custom_Widgets/CustomQuestionDialog.py
Normal file
35
Custom_Widgets/CustomQuestionDialog.py
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
class ooQuestionDialog(Gtk.Dialog):
|
||||
|
||||
hbox = None
|
||||
vbox = None
|
||||
|
||||
def __init__(self, title="Error!", parent=None,
|
||||
flags=Gtk.DialogFlags.MODAL,
|
||||
buttons=("NO", Gtk.ResponseType.NO, "_YES",
|
||||
Gtk.ResponseType.YES)):
|
||||
super().__init__(title=title, parent=parent, flags=flags,
|
||||
buttons=buttons)
|
||||
self.vbox = self.get_content_area()
|
||||
self.hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,
|
||||
spacing=5)
|
||||
icon_theme = Gtk.IconTheme.get_default()
|
||||
icon = icon_theme.load_icon("dialog-question", 48,
|
||||
Gtk.IconLookupFlags.FORCE_SVG)
|
||||
image = Gtk.Image.new_from_pixbuf(icon)
|
||||
self.hbox.pack_start(image, False, False, 5)
|
||||
self.vbox.add(self.hbox)
|
||||
|
||||
def set_message(self, message, add_msg=None):
|
||||
self.hbox.pack_start(Gtk.Label(message), False, False, 5)
|
||||
if add_msg != None:
|
||||
expander = Gtk.Expander.new_with_mnemonic( \
|
||||
"_Click me for more information.")
|
||||
expander.add(Gtk.Label(add_msg))
|
||||
self.vbox.pack_start(expander, False, False, 10)
|
||||
|
||||
def run(self):
|
||||
self.show_all()
|
||||
response = super().run()
|
||||
self.destroy()
|
||||
return response
|
63
Custom_Widgets/ImageLabelButtonClass.py
Normal file
63
Custom_Widgets/ImageLabelButtonClass.py
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class ImageLabelButton(Gtk.Button):
|
||||
|
||||
def __init__(self, orientation=Gtk.Orientation.HORIZONTAL,
|
||||
image="image-missing", label="Missing",
|
||||
*args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# now set up more properties
|
||||
hbox = Gtk.Box(orientation, spacing=0)
|
||||
if not isinstance(image, str):
|
||||
raise TypeError("Expected str, got %s instead." % str(image))
|
||||
icon_theme = Gtk.IconTheme.get_default()
|
||||
icon = icon_theme.load_icon(image, -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
img = Gtk.Image.new_from_pixbuf(icon)
|
||||
hbox.pack_start(img, True, True, 0)
|
||||
img.set_halign(Gtk.Align.END)
|
||||
if not isinstance(label, str):
|
||||
raise TypeError("Expected str, got %s instead." % str(label))
|
||||
if len(label) > 15:
|
||||
raise ValueError("The length of str may not exceed 15 characters.")
|
||||
labelwidget = Gtk.Label(label)
|
||||
hbox.pack_start(labelwidget, True, True, 0)
|
||||
labelwidget.set_halign(Gtk.Align.START)
|
||||
self.add(hbox)
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(25)
|
||||
button = ImageLabelButton(image="window-close", label="Close")
|
||||
button.connect("clicked", self.on_button_clicked)
|
||||
button.set_relief(Gtk.ReliefStyle.NORMAL)
|
||||
self.add(button)
|
||||
self.set_size_request(170, 50)
|
||||
|
||||
def on_button_clicked(self, button):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="ImageLabelButton")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
162
Custom_Widgets/Multi_Thread.py
Normal file
162
Custom_Widgets/Multi_Thread.py
Normal file
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys, threading, queue, time
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
def dbsim(q1, q2):
|
||||
while True:
|
||||
data = q1.get()
|
||||
# the request is always the same for our purpose
|
||||
items = {'lname':"Bunny", 'fname':"Bugs",
|
||||
'street':"Termite Terrace", 'city':"Hollywood",
|
||||
'state':"California", 'zip':"99999",
|
||||
'employer':"Warner Bros.", 'position':"Cartoon character",
|
||||
'credits':"Rabbit Hood, Haredevil Hare, What's Up Doc?"}
|
||||
q2.put(items)
|
||||
q1.task_done()
|
||||
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.lname = None
|
||||
self.fname = None
|
||||
self.street = None
|
||||
self.city = None
|
||||
self.state = None
|
||||
self.zip = None
|
||||
self.employer = None
|
||||
self.position = None
|
||||
self.credits = None
|
||||
self.q1 = queue.Queue()
|
||||
self.q2 = queue.Queue()
|
||||
self.thrd = threading.Thread(target=dbsim, daemon=True, args=(self.q1, self.q2))
|
||||
self.thrd.start()
|
||||
|
||||
# window setup
|
||||
self.set_border_width(10)
|
||||
grid = Gtk.Grid.new()
|
||||
grid.set_column_spacing(5)
|
||||
grid.set_row_spacing(5)
|
||||
# name
|
||||
label = Gtk.Label.new("Last name:")
|
||||
label.set_halign(Gtk.Align.END)
|
||||
grid.attach(label, 0, 0, 1, 1)
|
||||
self.lname = Gtk.Entry.new()
|
||||
grid.attach(self.lname, 1, 0, 1, 1)
|
||||
label = Gtk.Label.new("First name:")
|
||||
label.set_halign(Gtk.Align.END)
|
||||
grid.attach(label, 2, 0, 1, 1)
|
||||
self.fname = Gtk.Entry.new()
|
||||
grid.attach(self.fname, 3, 0, 1, 1)
|
||||
# address
|
||||
label = Gtk.Label.new("Street:")
|
||||
label.set_halign(Gtk.Align.END)
|
||||
grid.attach(label, 0, 1, 1, 1)
|
||||
self.street = Gtk.Entry.new()
|
||||
grid.attach(self.street, 1, 1, 1, 1)
|
||||
label = Gtk.Label.new("City:")
|
||||
label.set_halign(Gtk.Align.END)
|
||||
grid.attach(label, 2, 1, 1, 1)
|
||||
self.city = Gtk.Entry.new()
|
||||
grid.attach(self.city, 3, 1, 1, 1)
|
||||
label = Gtk.Label.new("State:")
|
||||
label.set_halign(Gtk.Align.END)
|
||||
grid.attach(label, 0, 2, 1, 1)
|
||||
self.state = Gtk.Entry.new()
|
||||
grid.attach(self.state, 1, 2, 1, 1)
|
||||
label = Gtk.Label.new("Zip:")
|
||||
label.set_halign(Gtk.Align.END)
|
||||
grid.attach(label, 2, 2, 1, 1)
|
||||
self.zip = Gtk.Entry.new()
|
||||
grid.attach(self.zip, 3, 2, 1, 1)
|
||||
# employment status
|
||||
label = Gtk.Label.new("Employer:")
|
||||
label.set_halign(Gtk.Align.END)
|
||||
grid.attach(label, 0, 3, 1, 1)
|
||||
self.employer = Gtk.Entry.new()
|
||||
grid.attach(self.employer, 1, 3, 1, 1)
|
||||
label = Gtk.Label.new("Position:")
|
||||
label.set_halign(Gtk.Align.END)
|
||||
grid.attach(label, 2, 3, 1, 1)
|
||||
self.position = Gtk.Entry.new()
|
||||
grid.attach(self.position, 3, 3, 1, 1)
|
||||
label = Gtk.Label.new("Credits:")
|
||||
label.set_halign(Gtk.Align.END)
|
||||
grid.attach(label, 0, 4, 1, 1)
|
||||
self.credits = Gtk.Entry.new()
|
||||
grid.attach(self.credits, 1, 4, 3, 1)
|
||||
# buttons
|
||||
bb = Gtk.ButtonBox(Gtk.Orientation.HORIZONTAL)
|
||||
load_button = Gtk.Button.new_with_label("Load")
|
||||
bb.pack_end(load_button, False, False, 0)
|
||||
load_button.connect("clicked", self.on_load_button_clicked)
|
||||
save_button = Gtk.Button.new_with_label("Save")
|
||||
bb.pack_end(save_button, False, False, 0)
|
||||
save_button.connect("clicked", self.on_save_button_clicked)
|
||||
cancel_button = Gtk.Button.new_with_label("Cancel")
|
||||
bb.pack_end(cancel_button, False, False, 0)
|
||||
cancel_button.connect("clicked", self.on_cancel_button_clicked)
|
||||
# box setup
|
||||
vbox = Gtk.Box.new(orientation=Gtk.Orientation.VERTICAL, spacing=5)
|
||||
vbox.add(grid)
|
||||
vbox.add(bb)
|
||||
self.add(vbox)
|
||||
|
||||
def on_cancel_button_clicked(self, button):
|
||||
self.destroy()
|
||||
|
||||
def on_load_button_clicked(self, button):
|
||||
self.q1.put('request')
|
||||
# wait for the results to be queued
|
||||
data = None
|
||||
while Gtk.events_pending() or data == None:
|
||||
Gtk.main_iteration()
|
||||
try:
|
||||
data = self.q2.get(block=False)
|
||||
except queue.Empty:
|
||||
continue
|
||||
self.lname.set_text(data['lname'])
|
||||
self.fname.set_text(data['fname'])
|
||||
self.street.set_text(data['street'])
|
||||
self.city.set_text(data['city'])
|
||||
self.state.set_text(data['state'])
|
||||
self.zip.set_text(data['zip'])
|
||||
self.employer.set_text(data['employer'])
|
||||
self.position.set_text(data['position'])
|
||||
self.credits.set_text(data['credits'])
|
||||
self.q2.task_done()
|
||||
|
||||
def on_save_button_clicked(self, button):
|
||||
self.lname.set_text("")
|
||||
self.fname.set_text("")
|
||||
self.street.set_text("")
|
||||
self.city.set_text("")
|
||||
self.state.set_text("")
|
||||
self.zip.set_text("")
|
||||
self.employer.set_text("")
|
||||
self.position.set_text("")
|
||||
self.credits.set_text("")
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Multi-Thread")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
65
Dialogs/ColorSelectionDialog.py
Normal file
65
Dialogs/ColorSelectionDialog.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
global_color = Gdk.RGBA(red=.50, green=.50, blue=.50, alpha=1.0).to_color()
|
||||
global_alpha = 65535
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, 100)
|
||||
modal = Gtk.Button.new_with_label("Modal")
|
||||
nonmodal = Gtk.Button.new_with_label("Non-Modal")
|
||||
modal.connect("clicked", self.on_run_color_selection_dialog,
|
||||
self, True)
|
||||
nonmodal.connect("clicked", self.on_run_color_selection_dialog,
|
||||
self, False)
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||
hbox.pack_start(modal, False, False, 5)
|
||||
hbox.pack_start(nonmodal, False, False, 5)
|
||||
self.add(hbox)
|
||||
|
||||
def on_dialog_response(self, dialog, result):
|
||||
if result == Gtk.ResponseType.OK:
|
||||
colorsel = dialog.get_color_selection()
|
||||
alpha = colorsel.get_current_alpha()
|
||||
color = colorsel.get_current_color()
|
||||
print(color.to_string())
|
||||
global_color = color
|
||||
global_alpha = alpha
|
||||
dialog.destroy()
|
||||
|
||||
def on_run_color_selection_dialog(self, button, window, domodal):
|
||||
if domodal:
|
||||
title = ("Choose Color -- Modal")
|
||||
else:
|
||||
title = ("Choose Color -- Non-Modal")
|
||||
dialog = Gtk.ColorSelectionDialog(title=title, parent=window, modal=domodal)
|
||||
colorsel = dialog.get_color_selection()
|
||||
colorsel.set_has_opacity_control(True)
|
||||
colorsel.set_current_color(global_color)
|
||||
dialog.connect("response", self.on_dialog_response)
|
||||
dialog.show_all()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Color Selection Dialog")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
128
Dialogs/Exercise_1.py
Normal file
128
Dialogs/Exercise_1.py
Normal file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
|
||||
savebutton = Gtk.Button.new_with_label("Save a File")
|
||||
createbutton = Gtk.Button.new_with_label("Create a New Folder")
|
||||
openbutton = Gtk.Button.new_with_label("Open One or More Files")
|
||||
selectbutton = Gtk.Button.new_with_label("Select a Folder")
|
||||
|
||||
savebutton.connect("clicked", self.on_save_clicked)
|
||||
createbutton.connect("clicked", self.on_create_clicked)
|
||||
openbutton.connect("clicked", self.on_open_clicked)
|
||||
selectbutton.connect("clicked", self.on_select_clicked)
|
||||
|
||||
vbox = Gtk.Box.new (Gtk.Orientation.VERTICAL, 5)
|
||||
vbox.pack_start(savebutton, False, False, 5)
|
||||
vbox.pack_start(createbutton, False, False, 5)
|
||||
vbox.pack_start(openbutton, False, False, 5)
|
||||
vbox.pack_start(selectbutton, False, False, 5)
|
||||
|
||||
self.add (vbox)
|
||||
|
||||
def on_save_clicked(self, button):
|
||||
dialog = Gtk.Dialog(title="Save File As ...",
|
||||
buttons=("Cancel", Gtk.ResponseType.CANCEL,
|
||||
"Save", Gtk.ResponseType.OK),
|
||||
parent=self)
|
||||
dialog.set_border_width(10)
|
||||
dialog.set_size_request(600, -1)
|
||||
chooser = Gtk.FileChooserWidget.new(Gtk.FileChooserAction.SAVE)
|
||||
|
||||
dialog.vbox.pack_start(chooser, False, False, 5)
|
||||
dialog.show_all()
|
||||
|
||||
result = dialog.run()
|
||||
if result == Gtk.ResponseType.OK:
|
||||
filename = chooser.get_filename()
|
||||
print("Saving file as: %s", filename)
|
||||
|
||||
dialog.destroy()
|
||||
|
||||
def on_create_clicked(self, button):
|
||||
dialog = Gtk.Dialog(title="Create a Folder",
|
||||
buttons=("Cancel", Gtk.ResponseType.CANCEL,
|
||||
"Create", Gtk.ResponseType.OK),
|
||||
parent=self)
|
||||
dialog.set_border_width(10)
|
||||
dialog.set_size_request(600, -1)
|
||||
chooser = Gtk.FileChooserWidget.new(Gtk.FileChooserAction.CREATE_FOLDER)
|
||||
|
||||
dialog.vbox.pack_start(chooser, False, False, 5)
|
||||
dialog.show_all()
|
||||
|
||||
result = dialog.run()
|
||||
if result == Gtk.ResponseType.OK:
|
||||
filename = chooser.get_filename()
|
||||
print("Creating directory: %s", filename)
|
||||
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
def on_open_clicked(self, button):
|
||||
dialog = Gtk.Dialog(title="Open file(s) ...",
|
||||
buttons=("Cancel", Gtk.ResponseType.CANCEL,
|
||||
"Open", Gtk.ResponseType.OK),
|
||||
parent=self)
|
||||
dialog.set_border_width(10)
|
||||
dialog.set_size_request(600, -1)
|
||||
chooser = Gtk.FileChooserWidget.new(Gtk.FileChooserAction.OPEN)
|
||||
chooser.set_select_multiple(True)
|
||||
|
||||
dialog.vbox.pack_start(chooser, False, False, 5)
|
||||
dialog.show_all()
|
||||
|
||||
result = dialog.run()
|
||||
if result == Gtk.ResponseType.OK:
|
||||
filenames = chooser.get_filenames()
|
||||
for filename in filenames:
|
||||
print("Open file: %s", filename)
|
||||
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
def on_select_clicked(self, button):
|
||||
dialog = Gtk.Dialog(title="Select Folder ...",
|
||||
buttons=("Cancel", Gtk.ResponseType.CANCEL,
|
||||
"Select", Gtk.ResponseType.OK),
|
||||
parent=self)
|
||||
dialog.set_border_width(10)
|
||||
dialog.set_size_request(600, -1)
|
||||
chooser = Gtk.FileChooserWidget.new(Gtk.FileChooserAction.SELECT_FOLDER)
|
||||
|
||||
dialog.vbox.pack_start(chooser, False, False, 5)
|
||||
dialog.show_all()
|
||||
|
||||
result = dialog.run()
|
||||
if result == Gtk.ResponseType.OK:
|
||||
filename = chooser.get_filename()
|
||||
print("Selected directory: %s", filename)
|
||||
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Exercise 1")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
46
Dialogs/FileChooserDialogFolderCreate.py
Normal file
46
Dialogs/FileChooserDialogFolderCreate.py
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, 100)
|
||||
button = Gtk.Button.new_with_label("Create a Folder ...")
|
||||
button.connect("clicked", self.on_button_clicked, self)
|
||||
self.add(button)
|
||||
|
||||
def on_button_clicked(self, button, parentwin):
|
||||
dialog = Gtk.FileChooserDialog(title="Create a Folder ...",
|
||||
parent=parentwin,
|
||||
action=Gtk.FileChooserAction.SAVE,
|
||||
buttons=("_Cancel",
|
||||
Gtk.ResponseType.CANCEL,
|
||||
"_Ok", Gtk.ResponseType.OK))
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
filename = dialog.get_filename();
|
||||
print("Creating directory: %s\n" % filename)
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Create Folder")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
52
Dialogs/FileChooserDialogMultipleFiles.py
Normal file
52
Dialogs/FileChooserDialogMultipleFiles.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, 100)
|
||||
button = Gtk.Button.new_with_label("Open file(s) ...")
|
||||
button.connect("clicked", self.on_button_clicked, self)
|
||||
self.add(button)
|
||||
|
||||
def on_button_clicked(self, button, parentwin):
|
||||
dialog = Gtk.FileChooserDialog(title="Open file(s) ...",
|
||||
parent=parentwin,
|
||||
action=Gtk.FileChooserAction.OPEN,
|
||||
buttons=("_Cancel",
|
||||
Gtk.ResponseType.CANCEL,
|
||||
"_Open", Gtk.ResponseType.ACCEPT))
|
||||
dialog.set_select_multiple(True)
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.ACCEPT:
|
||||
filenames = dialog.get_filenames()
|
||||
i = 0
|
||||
while i < len(filenames):
|
||||
file = filenames[i]
|
||||
print(file + " was selected.")
|
||||
i += 1
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Open Nultiple Files")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
46
Dialogs/FileChooserDialog_Saving.py
Normal file
46
Dialogs/FileChooserDialog_Saving.py
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, 100)
|
||||
button = Gtk.Button.new_with_label("Save as ...")
|
||||
button.connect("clicked", self.on_button_clicked, self)
|
||||
self.add(button)
|
||||
|
||||
def on_button_clicked(self, button, parentwin):
|
||||
dialog = Gtk.FileChooserDialog(title="Save file as ...",
|
||||
parent=parentwin,
|
||||
action=Gtk.FileChooserAction.SAVE,
|
||||
buttons=("_Cancel",
|
||||
Gtk.ResponseType.CANCEL,
|
||||
"_Save", Gtk.ResponseType.ACCEPT))
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.ACCEPT:
|
||||
filename = dialog.get_filename()
|
||||
button.set_label(filename)
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Save a File")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
58
Dialogs/FontSelectionDialog.py
Normal file
58
Dialogs/FontSelectionDialog.py
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, 100)
|
||||
button = Gtk.Button.new_with_label("Run Font Selection Dialog")
|
||||
button.connect("clicked", self.on_run_font_selection_dialog)
|
||||
self.add(button)
|
||||
|
||||
def on_run_font_selection_dialog(self, button):
|
||||
dialog = Gtk.FontSelectionDialog(title="Choose a Font",
|
||||
buttons=("Apply", Gtk.ResponseType.APPLY),
|
||||
parent=self)
|
||||
dialog.set_preview_text("GTK+ 3 Development With Python")
|
||||
dialog.connect("response", self.on_dialog_response)
|
||||
# dialog.show_all()
|
||||
dialog.run()
|
||||
|
||||
def on_dialog_response(self, dialog, response):
|
||||
if response == Gtk.ResponseType.OK or response == Gtk.ResponseType.APPLY:
|
||||
font = dialog.get_font_name()
|
||||
message = Gtk.MessageDialog(title="Selected Font",
|
||||
flags=Gtk.DialogFlags.MODAL,
|
||||
type=Gtk.MessageType.INFO,
|
||||
text=font,
|
||||
buttons=("Ok", Gtk.ResponseType.OK),
|
||||
parent=dialog);
|
||||
message.run()
|
||||
message.destroy()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
dialog.destroy()
|
||||
else:
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Font Selection Dialog")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
59
Dialogs/GtkAboutDialogWidget.py
Normal file
59
Dialogs/GtkAboutDialogWidget.py
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, GdkPixbuf
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
button = Gtk.Button.new_with_mnemonic("_Click Me")
|
||||
button.connect("clicked", self.on_button_clicked, self)
|
||||
self.add(button)
|
||||
self.set_size_request(150, 50)
|
||||
self.show_all()
|
||||
|
||||
def on_button_clicked(self, button, parent):
|
||||
authors = ["Author #1", "Author #2"]
|
||||
documenters = ["Documenter #1", "Documenter #2"]
|
||||
dialog = Gtk.AboutDialog(parent=parent)
|
||||
logo = GdkPixbuf.Pixbuf.new_from_file("./logo.png")
|
||||
if logo != None:
|
||||
dialog.set_logo(logo)
|
||||
else:
|
||||
print("A GdkPixbuf Error has occurred.")
|
||||
dialog.set_name("Gtk.AboutDialog")
|
||||
dialog.set_version("3.0")
|
||||
dialog.set_copyright("(C) 2007 Andrew Krause")
|
||||
dialog.set_comments("All about Gtk.AboutDialog")
|
||||
dialog.set_license("Free to all!")
|
||||
dialog.set_website("http://book.andrewKrause.net")
|
||||
dialog.set_website_label("book.andrewkrause.net")
|
||||
dialog.set_authors(authors)
|
||||
dialog.set_documenters(documenters)
|
||||
dialog.set_translator_credits("Translator #1\nTranslator #2")
|
||||
dialog.connect("response", self.on_dialog_button_clicked)
|
||||
dialog.run()
|
||||
|
||||
def on_dialog_button_clicked(self, dialog, response):
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="About Dialog")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
128
Dialogs/GtkAssistant.py
Normal file
128
Dialogs/GtkAssistant.py
Normal file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
import time
|
||||
|
||||
class assistant(Gtk.Assistant):
|
||||
progress = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_size_request(450, 300)
|
||||
self.set_title("Gtk.Assistant Example")
|
||||
self.connect("destroy", Gtk.main_quit, None)
|
||||
# create page 0
|
||||
page0_widget = Gtk.Label("This in an example of a Gtk.Assistant. By\n" +
|
||||
"clicking the forward button, you can " +
|
||||
"continue\nto the next section!")
|
||||
self.append_page(page0_widget)
|
||||
self.set_page_title(page0_widget, "Introduction")
|
||||
self.set_page_type(page0_widget, Gtk.AssistantPageType.INTRO)
|
||||
self.set_page_complete(page0_widget, True)
|
||||
# create page 1
|
||||
page1_widget = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
|
||||
label = Gtk.Label("Your Name: ")
|
||||
entry = Gtk.Entry()
|
||||
page1_widget.pack_start(label, False, False, 5)
|
||||
page1_widget.pack_start(entry, False, False, 5)
|
||||
self.append_page(page1_widget)
|
||||
self.set_page_title(page1_widget, "")
|
||||
self.set_page_type(page1_widget, Gtk.AssistantPageType.CONTENT)
|
||||
self.set_page_complete(page1_widget, False)
|
||||
# create page 2
|
||||
page2_widget = Gtk.CheckButton.new_with_label("Click me to Continue!")
|
||||
self.append_page(page2_widget)
|
||||
self.set_page_title(page2_widget, "Click the Check Button")
|
||||
self.set_page_type(page2_widget, Gtk.AssistantPageType.CONTENT)
|
||||
self.set_page_complete(page2_widget, False)
|
||||
# create page 3
|
||||
page3_widget = Gtk.Alignment.new(0.5, 0.5, 0.0, 0.0)
|
||||
button = Gtk.Button.new_with_label("Click Me!")
|
||||
self.progress = Gtk.ProgressBar()
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
|
||||
hbox.pack_start(self.progress, True, False, 5)
|
||||
hbox.pack_start(button, False, False, 5)
|
||||
page3_widget.add(hbox)
|
||||
self.append_page(page3_widget)
|
||||
self.set_page_title(page3_widget, "Click the Check Button")
|
||||
self.set_page_type(page3_widget, Gtk.AssistantPageType.PROGRESS)
|
||||
self.set_page_complete(page3_widget, False)
|
||||
# create page 4
|
||||
page4_widget = Gtk.Label("Text has been entered in the label and the\n" +
|
||||
"combo box is clicked. If you are done, then\n" +
|
||||
"it is time to leave!")
|
||||
self.append_page(page4_widget)
|
||||
self.set_page_title(page4_widget, "Confirmation")
|
||||
self.set_page_type(page4_widget, Gtk.AssistantPageType.CONFIRM)
|
||||
self.set_page_complete(page4_widget, True)
|
||||
# set up the callbacks
|
||||
entry.connect("changed", self.entry_changed)
|
||||
page2_widget.connect("toggled", self.button_toggled)
|
||||
button.connect("clicked", self.button_clicked)
|
||||
self.connect("cancel", self.assistant_canceled)
|
||||
self.connect("close", self.assistant_close)
|
||||
|
||||
def entry_changed(self, entry):
|
||||
text = entry.get_text()
|
||||
num = self.get_current_page()
|
||||
page = self.get_nth_page(num)
|
||||
self.set_page_complete(page, len(text) > 0)
|
||||
|
||||
def button_toggled(self, toggle):
|
||||
active = toggle.get_active()
|
||||
self.set_page_complete(toggle, active)
|
||||
|
||||
def button_clicked(self, button):
|
||||
percent = 0.0
|
||||
button.set_sensitive(False)
|
||||
page = self.get_nth_page(3)
|
||||
while (percent <= 100.0):
|
||||
message = str(percent) + " complete"
|
||||
print(message)
|
||||
self.progress.set_fraction(percent / 100.0)
|
||||
self.progress.set_text(message)
|
||||
while (Gtk.events_pending()):
|
||||
Gtk.main_iteration()
|
||||
time.sleep(1)
|
||||
percent += 5.0
|
||||
self.set_page_complete(page, True)
|
||||
|
||||
def assistant_canceled(self, response):
|
||||
self.destroy()
|
||||
|
||||
def assistant_close(self, response):
|
||||
print("You would apply your changes now!")
|
||||
self.destroy()
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(25)
|
||||
button = Gtk.Button.new_with_mnemonic("_Open Assistant")
|
||||
button.connect("clicked", self.on_start_button_clicked)
|
||||
button.set_relief(Gtk.ReliefStyle.NORMAL)
|
||||
self.add(button)
|
||||
self.set_size_request(200, 100)
|
||||
|
||||
def on_start_button_clicked(self, button):
|
||||
assistant()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Gtk.Assistant")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
48
Dialogs/GtkMessageDialog.py
Normal file
48
Dialogs/GtkMessageDialog.py
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
button = Gtk.Button.new_with_mnemonic("_Click Me")
|
||||
button.connect("clicked", self.on_button_clicked, self)
|
||||
self.add(button)
|
||||
self.set_size_request(150, 50)
|
||||
|
||||
def on_button_clicked(self, button, parent):
|
||||
dialog = Gtk.Dialog(title="Information", parent=parent,
|
||||
flags=Gtk.DialogFlags.MODAL)
|
||||
dialog.add_button("Ok", Gtk.ResponseType.OK)
|
||||
label = Gtk.Label("The button was clicked.")
|
||||
image = Gtk.Image.new_from_icon_name("dialog-information",
|
||||
Gtk.IconSize.DIALOG)
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||
hbox.pack_start(image, False, False, 0)
|
||||
hbox.pack_start(label, False, False, 0)
|
||||
dialog.vbox.pack_start(hbox, False, False, 0)
|
||||
dialog.show_all()
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Dialogs")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
42
Dialogs/GtkMessageDialogWidget.py
Normal file
42
Dialogs/GtkMessageDialogWidget.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
button = Gtk.Button.new_with_mnemonic("_Click Me")
|
||||
button.connect("clicked", self.on_button_clicked, self)
|
||||
self.add(button)
|
||||
self.set_size_request(150, 50)
|
||||
|
||||
def on_button_clicked(self, button, parent):
|
||||
dialog = Gtk.MessageDialog(type=Gtk.MessageType.INFO, parent=parent,
|
||||
flags=Gtk.DialogFlags.MODAL,
|
||||
buttons=("Ok", Gtk.ResponseType.OK),
|
||||
text="The button was clicked.",
|
||||
title="Information")
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Dialogs")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
75
Dialogs/SimpleDialog.py
Normal file
75
Dialogs/SimpleDialog.py
Normal file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
import os
|
||||
import getpass
|
||||
import socket
|
||||
import pwd
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
button = Gtk.Button.new_with_mnemonic("_Click Me")
|
||||
button.connect("clicked", self.on_button_clicked, self)
|
||||
self.add(button)
|
||||
self.set_size_request(180, 50)
|
||||
self.show_all()
|
||||
|
||||
def on_button_clicked(self, button, parent):
|
||||
dialog = Gtk.Dialog(title="Edit User Information", parent=parent,
|
||||
flags=Gtk.DialogFlags.MODAL)
|
||||
dialog.add_button("Ok", Gtk.ResponseType.OK)
|
||||
dialog.add_button("Cancel", Gtk.ResponseType.CANCEL)
|
||||
dialog.set_default_response(Gtk.ResponseType.OK)
|
||||
lbl1 = Gtk.Label("User Name:")
|
||||
lbl2 = Gtk.Label("Real Name:")
|
||||
lbl3 = Gtk.Label("Home Dir:")
|
||||
lbl4 = Gtk.Label("Host Name:")
|
||||
user = Gtk.Entry()
|
||||
real_name = Gtk.Entry()
|
||||
home = Gtk.Entry()
|
||||
host = Gtk.Entry()
|
||||
user.set_text(getpass.getuser())
|
||||
real_name.set_text(pwd.getpwuid(os.getuid())[4])
|
||||
home.set_text(os.environ['HOME'])
|
||||
host.set_text(socket.gethostname())
|
||||
grid = Gtk.Grid()
|
||||
grid.attach(lbl1, 0, 0, 1, 1)
|
||||
grid.attach(lbl2, 0, 1, 1, 1)
|
||||
grid.attach(lbl3, 0, 2, 1, 1)
|
||||
grid.attach(lbl4, 0, 3, 1, 1)
|
||||
grid.attach(user, 1, 0, 1, 1)
|
||||
grid.attach(real_name, 1, 1, 1, 1)
|
||||
grid.attach(home, 1, 2, 1, 1)
|
||||
grid.attach(host, 1, 3, 1, 1)
|
||||
dialog.vbox.pack_start(grid, False, False, 5)
|
||||
dialog.show_all()
|
||||
result = dialog.run()
|
||||
if result == Gtk.ResponseType.OK:
|
||||
print("User Name: " + user.get_text())
|
||||
print("Real Name: " + real_name.get_text())
|
||||
print("Home: " + home.get_text())
|
||||
print("Host: " + host.get_text())
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Simple Dialog")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
50
Dialogs/nonmodalGtkMessageDialog.py
Normal file
50
Dialogs/nonmodalGtkMessageDialog.py
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
button = Gtk.Button.new_with_mnemonic("_Click Me")
|
||||
button.connect("clicked", self.on_button_clicked, self)
|
||||
self.add(button)
|
||||
self.set_size_request(150, 50)
|
||||
self.show_all()
|
||||
|
||||
def on_button_clicked(self, button, parent):
|
||||
dialog = Gtk.Dialog(title="Information", parent=parent)
|
||||
dialog.add_button("Ok", Gtk.ResponseType.OK)
|
||||
label = Gtk.Label("The button was clicked.")
|
||||
image = Gtk.Image.new_from_icon_name("dialog-information",
|
||||
Gtk.IconSize.DIALOG)
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||
hbox.pack_start(image, False, False, 0)
|
||||
hbox.pack_start(label, False, False, 0)
|
||||
dialog.vbox.pack_start(hbox, False, False, 0)
|
||||
dialog.connect("response", self.on_dialog_button_clicked)
|
||||
dialog.show_all()
|
||||
|
||||
def on_dialog_button_clicked(self, dialog, response):
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Dialogs")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
192
Dynamic_User_Interfaces/Exercise_1.glade
Normal file
192
Dynamic_User_Interfaces/Exercise_1.glade
Normal file
@@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">edit-find</property>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<property name="width_request">600</property>
|
||||
<property name="height_request">450</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="valign">start</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="toolbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_New</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">document-new</property>
|
||||
<signal name="clicked" handler="on_new_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="toolbutton2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">document-open</property>
|
||||
<signal name="clicked" handler="on_open_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="_Save">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">document-save</property>
|
||||
<signal name="clicked" handler="on_save_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem" id="separatortoolitem1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="toolbutton4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">C_ut</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">edit-cut</property>
|
||||
<signal name="clicked" handler="on_cut_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="toolbutton5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Copy</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">edit-copy</property>
|
||||
<signal name="clicked" handler="on_copy_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="toolbutton6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Paste</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">edit-paste</property>
|
||||
<signal name="clicked" handler="on_paste_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry1">
|
||||
<property name="width_request">250</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="text" translatable="yes">Search for ...</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label" translatable="yes">Find</property>
|
||||
<property name="width_request">-1</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
47
Dynamic_User_Interfaces/Exercise_1.py
Normal file
47
Dynamic_User_Interfaces/Exercise_1.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class SignalHandlers():
|
||||
|
||||
def on_new_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_open_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_save_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_cut_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_copy_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_paste_clicked(self, button ):
|
||||
pass
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file("./Exercise_1.glade")
|
||||
self.window = builder.get_object("window")
|
||||
self.add_window(self.window)
|
||||
builder.connect_signals(SignalHandlers())
|
||||
self.add_window(self.window)
|
||||
self.window.show_all()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
215
Dynamic_User_Interfaces/Exercise_2.glade
Normal file
215
Dynamic_User_Interfaces/Exercise_2.glade
Normal file
@@ -0,0 +1,215 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">edit-find</property>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<property name="width_request">600</property>
|
||||
<property name="height_request">450</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkMenuBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="menuitem1">
|
||||
<property name="label" translatable="yes">_New</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_new_clicked" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="menuitem2">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_open_clicked" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="menuitem3">
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_save_clicked" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Edit</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="menuitem4">
|
||||
<property name="label" translatable="yes">C_ut</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_cut_clicked" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="menuitem5">
|
||||
<property name="label" translatable="yes">_Copy</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_copy_clicked" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="menuitem6">
|
||||
<property name="label" translatable="yes">_Paste</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_paste_clicked" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry1">
|
||||
<property name="width_request">250</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="text" translatable="yes">Search for ...</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label" translatable="yes">Find</property>
|
||||
<property name="width_request">-1</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
47
Dynamic_User_Interfaces/Exercise_2.py
Normal file
47
Dynamic_User_Interfaces/Exercise_2.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class SignalHandlers():
|
||||
|
||||
def on_new_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_open_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_save_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_cut_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_copy_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_paste_clicked(self, button ):
|
||||
pass
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file("./Exercise_2.glade")
|
||||
self.window = builder.get_object("window")
|
||||
self.add_window(self.window)
|
||||
builder.connect_signals(SignalHandlers())
|
||||
self.add_window(self.window)
|
||||
self.window.show_all()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
253
Dynamic_User_Interfaces/FileBrowser.glade
Normal file
253
Dynamic_User_Interfaces/FileBrowser.glade
Normal file
@@ -0,0 +1,253 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkWindow" id="main_window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">File Browser</property>
|
||||
<signal name="destroy" handler="on_window_destroy" swapped="no"/>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="toolbar_style">both</property>
|
||||
<property name="icon_size">2</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="back_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Back</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-go-back</property>
|
||||
<signal name="clicked" handler="on_back_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="forward_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Forward</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-go-forward</property>
|
||||
<signal name="clicked" handler="on_forward_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="up_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Up</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-go-up</property>
|
||||
<signal name="clicked" handler="on_up_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="refresh_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Refresh</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-refresh</property>
|
||||
<signal name="clicked" handler="on_refresh_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="home_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Home</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-home</property>
|
||||
<signal name="clicked" handler="on_home_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="delete_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Delete</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-delete</property>
|
||||
<signal name="clicked" handler="on_delete_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="info_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Information</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-dialog-info</property>
|
||||
<signal name="clicked" handler="on_info_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xpad">5</property>
|
||||
<property name="ypad">5</property>
|
||||
<property name="label" translatable="yes">Current Location:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="location_edit">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="activate" handler="on_location_activate" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="go_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_go_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-jump-to</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Go</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeview_list">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="row-activated" handler="on_row_activated" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
62
Dynamic_User_Interfaces/LoadFileBrowser.py
Normal file
62
Dynamic_User_Interfaces/LoadFileBrowser.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class SignalHandlers():
|
||||
|
||||
def on_back_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_forward_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_up_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_refresh_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_home_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_delete_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_info_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_go_clicked(self, button ):
|
||||
pass
|
||||
|
||||
def on_location_activate(self, button ):
|
||||
pass
|
||||
|
||||
def on_row_activated(self, button ):
|
||||
pass
|
||||
|
||||
def on_window_destroy(self, button ):
|
||||
pass
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file("./FileBrowser.glade")
|
||||
self.window = builder.get_object("main_window")
|
||||
self.add_window(self.window)
|
||||
builder.connect_signals(SignalHandlers())
|
||||
self.add_window(self.window)
|
||||
self.window.show_all()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
317
Integrating/Calculator.glade
Normal file
317
Integrating/Calculator.glade
Normal file
@@ -0,0 +1,317 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<property name="name">Calculator</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_menubar">False</property>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">7</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="output">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="margin_top">3</property>
|
||||
<property name="margin_bottom">3</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="has_frame">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="input_purpose">number</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">3</property>
|
||||
<property name="margin_right">3</property>
|
||||
<property name="margin_bottom">4</property>
|
||||
<property name="row_spacing">7</property>
|
||||
<property name="column_spacing">7</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="power">
|
||||
<property name="label" translatable="yes">Xy</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_op_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">4</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="squareroo">
|
||||
<property name="label" translatable="yes">Sqrt</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_sqrt_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">4</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="sign">
|
||||
<property name="label" translatable="yes">+/-</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_sign_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">4</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="add">
|
||||
<property name="label" translatable="yes">+</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_op_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="sub">
|
||||
<property name="label" translatable="yes">-</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_op_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="mul">
|
||||
<property name="label" translatable="yes">X</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_op_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="equal">
|
||||
<property name="label" translatable="yes">=</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_equal_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_3">
|
||||
<property name="label" translatable="yes">3</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_6">
|
||||
<property name="label" translatable="yes">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="clear">
|
||||
<property name="label" translatable="yes">Clr</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_clear_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">4</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="div">
|
||||
<property name="label" translatable="yes">/</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_op_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_9">
|
||||
<property name="label" translatable="yes">9</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="decimal">
|
||||
<property name="label" translatable="yes">.</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_2">
|
||||
<property name="label" translatable="yes">2</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_5">
|
||||
<property name="label" translatable="yes">5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_8">
|
||||
<property name="label" translatable="yes">8</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_0">
|
||||
<property name="label" translatable="yes">0</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_1">
|
||||
<property name="label" translatable="yes">1</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_4">
|
||||
<property name="label" translatable="yes">4</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="num_7">
|
||||
<property name="label" translatable="yes">7</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="on_num_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
178
Integrating/Calculator.py
Normal file
178
Integrating/Calculator.py
Normal file
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import math
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Pango
|
||||
|
||||
|
||||
|
||||
class SignalHandlers():
|
||||
|
||||
def __init__(self, builder):
|
||||
self.builder = builder
|
||||
self.entry = None
|
||||
self.OP_NULL = 0
|
||||
self.OP_ADD = 1
|
||||
self.OP_SUBTRACT = 2
|
||||
self.OP_MULTIPLY = 3
|
||||
self.OP_DIVIDE = 4
|
||||
self.OP_POWER = 5
|
||||
self.clear_value = False
|
||||
self.value_set = False
|
||||
self.prev_value = 0
|
||||
self.pending_op = self.OP_NULL
|
||||
|
||||
entry = builder.get_object("output")
|
||||
self.entry = entry
|
||||
fd = Pango.font_description_from_string("Monospace Bold 16")
|
||||
entry.set_text("0")
|
||||
entry.modify_font(fd)
|
||||
|
||||
# Set user data for the operators and decimal buttons.
|
||||
add = builder.get_object("add")
|
||||
add.operator = self.OP_ADD
|
||||
sub = builder.get_object("sub")
|
||||
sub.operator = self.OP_SUBTRACT
|
||||
mul = builder.get_object("mul")
|
||||
mul.operator = self.OP_MULTIPLY
|
||||
div = builder.get_object("div")
|
||||
div.operator = self.OP_DIVIDE
|
||||
power = builder.get_object("power")
|
||||
power.operator = self.OP_POWER
|
||||
decimal = builder.get_object("decimal")
|
||||
decimal.number = 10
|
||||
|
||||
# Set the user data for the number buttons.
|
||||
for i in range(0, 10):
|
||||
name = "num_%i" % (i,)
|
||||
num = builder.get_object(name)
|
||||
num.number = i
|
||||
|
||||
def do_operation(self, entry, value):
|
||||
# Perform the specified operation, either add, subtract, multiply,
|
||||
# divide, or the power operation.
|
||||
|
||||
# Perform the operation on prev_value with the new value and store
|
||||
# the result back into prev_value.
|
||||
if self.pending_op == self.OP_ADD:
|
||||
self.prev_value += value
|
||||
elif self.pending_op == self.OP_SUBTRACT:
|
||||
self.prev_value -= value
|
||||
elif self.pending_op == self.OP_MULTIPLY:
|
||||
self.prev_value *= value
|
||||
elif self.pending_op == self.OP_DIVIDE:
|
||||
self.prev_value /= value;
|
||||
elif self.pending_op == self.OP_POWER:
|
||||
self.prev_value = pow(prev_value, value)
|
||||
else:
|
||||
return
|
||||
|
||||
# Reset the pending operation and create a string with the new value.
|
||||
self.pending_op = self.OP_NULL
|
||||
entry.set_text(self.format_num(self.prev_value))
|
||||
|
||||
def on_num_clicked(self, button):
|
||||
# Retrieve the number that is stored in user data.
|
||||
num = button.number
|
||||
|
||||
# Clear the value if a new number should be entered.
|
||||
if self.clear_value:
|
||||
self.entry.set_text("0")
|
||||
self.clear_value = False
|
||||
|
||||
# Append a decimal place to the GtkEntry. Make sure to keep track of
|
||||
# whether the decimal place was already entered.
|
||||
text = self.entry.get_text()
|
||||
if (num == 10):
|
||||
if len(text) > 9:
|
||||
return
|
||||
elif text.find('.') >= 0:
|
||||
return
|
||||
else:
|
||||
text = text + '.'
|
||||
# Append a number place to the GtkEntry if the length is less than 10.
|
||||
else:
|
||||
text = text + str(num)
|
||||
if len(text) > 10:
|
||||
return
|
||||
# Remove preceeding zeros.
|
||||
text = text.lstrip('0')
|
||||
self.entry.set_text(text)
|
||||
|
||||
def on_equal_clicked(self, button):
|
||||
# Perform any pending operations because the equal button was pressed.
|
||||
value = float(self.entry.get_text())
|
||||
|
||||
self.do_operation(self.entry, value)
|
||||
self.clear_value = True
|
||||
self.value_set = False
|
||||
|
||||
def on_op_clicked(self, button):
|
||||
op = button.operator
|
||||
value = float(self.entry.get_text())
|
||||
|
||||
# Perform any pending operations and then store the new operation.
|
||||
self.do_operation(self.entry, value)
|
||||
self.pending_op = op;
|
||||
self.clear_value = True
|
||||
|
||||
# Set the current value as the previous value if it should be
|
||||
# overwritten.
|
||||
if not self.value_set:
|
||||
self.prev_value = value;
|
||||
self.value_set = True
|
||||
|
||||
def on_sign_clicked(self, button):
|
||||
value = float(self.entry.get_text())
|
||||
|
||||
# You cannot negate a value of zero.
|
||||
if value == 0.0:
|
||||
return
|
||||
value *= -1
|
||||
|
||||
self.entry.set_text(self.format_num(value))
|
||||
|
||||
def on_sqrt_clicked(self, button):
|
||||
# Take the square root of the current value.
|
||||
value = math.sqrt(float(self.entry.get_text()))
|
||||
|
||||
self.entry.set_text(self.format_num(value))
|
||||
|
||||
def on_clear_clicked(self, button):
|
||||
self.entry.set_text("0")
|
||||
|
||||
self.clear_value = False
|
||||
self.value_set = False
|
||||
self.prev_value = 0
|
||||
self.pending_op = self.OP_NULL
|
||||
|
||||
def format_num(self, num):
|
||||
text = str(num)
|
||||
text = text.rstrip('0')
|
||||
text = text.lstrip('0')
|
||||
text = text.rstrip('.') # remove trailing decimal
|
||||
return text
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
self.builder = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.builder = Gtk.Builder()
|
||||
self.builder.add_from_file("./Calculator.glade")
|
||||
self.window = self.builder.get_object("window")
|
||||
self.builder.connect_signals(SignalHandlers(self.builder))
|
||||
self.add_window(self.window)
|
||||
self.window.show_all()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
||||
|
432
Integrating/Calendar.glade
Normal file
432
Integrating/Calendar.glade
Normal file
@@ -0,0 +1,432 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">window-close</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">list-add</property>
|
||||
</object>
|
||||
<object class="GtkListStore" id="liststore">
|
||||
<columns>
|
||||
<!-- column-name event_name -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name location -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name event)time -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<property name="height_request">-1</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">3</property>
|
||||
<property name="margin_bottom">3</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar" id="toolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="toolbar_style">both</property>
|
||||
<property name="icon_size">2</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="new">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">document-new</property>
|
||||
<signal name="clicked" handler="on_new_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="open">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Open</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">document-open</property>
|
||||
<signal name="clicked" handler="on_open_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="add">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Add Event</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">list-add</property>
|
||||
<signal name="clicked" handler="on_add_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="remove">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Remove</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">list-remove</property>
|
||||
<signal name="clicked" handler="on_remove_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="clear">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Clear All</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">edit-cut</property>
|
||||
<signal name="clicked" handler="on_clear_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned" id="hpand1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="name">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Create or open a calendar ...</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCalendar" id="calendar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="year">2018</property>
|
||||
<property name="month">5</property>
|
||||
<property name="day">28</property>
|
||||
<signal name="day-selected" handler="on_day_changed" swapped="no"/>
|
||||
<signal name="month-changed" handler="on_month_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
|
||||
<property name="margin_left">1</property>
|
||||
<property name="margin_right">1</property>
|
||||
<property name="margin_top">1</property>
|
||||
<property name="margin_bottom">1</property>
|
||||
<property name="model">liststore</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeselection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkDialog" id="dialog">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Add a New Event</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="transient_for">window</property>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog-vbox1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog_action_area">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label" translatable="yes">Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image1</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button2">
|
||||
<property name="label" translatable="yes">Add Event</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image2</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">3</property>
|
||||
<property name="margin_bottom">3</property>
|
||||
<property name="row_spacing">7</property>
|
||||
<property name="column_spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Name:</property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Location:</property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Start Time:</property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">End Time:</property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="event_name">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="location">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="start_time">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<items>
|
||||
<item translatable="yes">All Day</item>
|
||||
<item translatable="yes">00:00</item>
|
||||
<item translatable="yes">01:00</item>
|
||||
<item translatable="yes">02:00</item>
|
||||
<item translatable="yes">03:00</item>
|
||||
<item translatable="yes">04:00</item>
|
||||
<item translatable="yes">05:00</item>
|
||||
<item translatable="yes">06:00</item>
|
||||
<item translatable="yes">07:00</item>
|
||||
<item translatable="yes">08:00</item>
|
||||
<item translatable="yes">09:00</item>
|
||||
<item translatable="yes">10:00</item>
|
||||
<item translatable="yes">11:00</item>
|
||||
<item translatable="yes">12:00</item>
|
||||
<item translatable="yes">13:00</item>
|
||||
<item translatable="yes">14:00</item>
|
||||
<item translatable="yes">15:00</item>
|
||||
<item translatable="yes">16:00</item>
|
||||
<item translatable="yes">17:00</item>
|
||||
<item translatable="yes">18:00</item>
|
||||
<item translatable="yes">19:00</item>
|
||||
<item translatable="yes">20:00</item>
|
||||
<item translatable="yes">21:00</item>
|
||||
<item translatable="yes">22:00</item>
|
||||
<item translatable="yes">23:00</item>
|
||||
</items>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="end_time">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<items>
|
||||
<item translatable="yes">02:00</item>
|
||||
<item translatable="yes">03:00</item>
|
||||
<item translatable="yes">04:00</item>
|
||||
<item translatable="yes">05:00</item>
|
||||
<item translatable="yes">06:00</item>
|
||||
<item translatable="yes">07:00</item>
|
||||
<item translatable="yes">08:00</item>
|
||||
<item translatable="yes">09:00</item>
|
||||
<item translatable="yes">10:00</item>
|
||||
<item translatable="yes">11:00</item>
|
||||
<item translatable="yes">12:00</item>
|
||||
<item translatable="yes">13:00</item>
|
||||
<item translatable="yes">14:00</item>
|
||||
<item translatable="yes">15:00</item>
|
||||
<item translatable="yes">16:00</item>
|
||||
<item translatable="yes">17:00</item>
|
||||
<item translatable="yes">18:00</item>
|
||||
<item translatable="yes">19:00</item>
|
||||
<item translatable="yes">20:00</item>
|
||||
<item translatable="yes">21:00</item>
|
||||
<item translatable="yes">22:00</item>
|
||||
<item translatable="yes">23:00</item>
|
||||
<item translatable="yes">24:00</item>
|
||||
</items>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">button1</action-widget>
|
||||
<action-widget response="-10">button2</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
277
Integrating/Calendar.py
Normal file
277
Integrating/Calendar.py
Normal file
@@ -0,0 +1,277 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import xml.sax
|
||||
import time
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
class Event():
|
||||
# A structure used to hold a single event.
|
||||
def __init__(self):
|
||||
self.name = None
|
||||
self.location = None
|
||||
self.day = None
|
||||
self.month = None
|
||||
self.year = None
|
||||
self.start = None
|
||||
self.end = None
|
||||
|
||||
|
||||
class CalendarContentHandler(xml.sax.ContentHandler):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.event = None # the current event
|
||||
self.tag_name = None # the current xml tag name
|
||||
self.events = [] # the list of events
|
||||
|
||||
def startElement(self, name, attrs):
|
||||
if name == "event":
|
||||
self.event = Event()
|
||||
self.tag_name = name
|
||||
|
||||
def endElement(self, name):
|
||||
if name == "event":
|
||||
self.events.append(self.event)
|
||||
|
||||
def characters(self, content):
|
||||
cdata = content.strip()
|
||||
if cdata == None or cdata == "":
|
||||
return
|
||||
if self.tag_name == "name":
|
||||
self.event.name = cdata
|
||||
elif self.tag_name == "location":
|
||||
self.event.location = cdata
|
||||
elif self.tag_name == "day":
|
||||
self.event.day = cdata
|
||||
elif self.tag_name == "month":
|
||||
self.event.month = cdata
|
||||
elif self.tag_name == "year":
|
||||
self.event.year = cdata
|
||||
elif self.tag_name == "start":
|
||||
self.event.start = cdata
|
||||
elif self.tag_name == "end":
|
||||
self.event.end = cdata
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
class SignalHandlers():
|
||||
|
||||
def __init__(self, builder):
|
||||
self.builder = builder
|
||||
self.events = [] # the list of events
|
||||
self.NAME = 0 # treeview column 1
|
||||
self.LOCATION = 1 # treeview column 2
|
||||
self.TIME = 2 # treeview column 3
|
||||
self.filename = None # the current events file
|
||||
|
||||
|
||||
def on_new_clicked(self, button):
|
||||
window = self.builder.get_object("window")
|
||||
dialog = Gtk.FileChooserDialog(title="Create a New Calendar",
|
||||
action=Gtk.FileChooserAction.SAVE,
|
||||
modal=True, parent=window,
|
||||
buttons=("Cancel",
|
||||
Gtk.ResponseType.CANCEL,
|
||||
"Save",
|
||||
Gtk.ResponseType.ACCEPT))
|
||||
dialog.set_do_overwrite_confirmation(False)
|
||||
result = dialog.run()
|
||||
if result == Gtk.ResponseType.ACCEPT:
|
||||
self.save_calendar_list()
|
||||
self.filename = dialog.get_filename()
|
||||
self.events = []
|
||||
self. load_calendar_list(self.filename)
|
||||
calendar = self.builder.get_object("calendar")
|
||||
self.on_day_changed(calendar)
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
def on_open_clicked(self, button):
|
||||
window = self.builder.get_object("window")
|
||||
dialog = Gtk.FileChooserDialog(title="Open a New Calendar",
|
||||
action=Gtk.FileChooserAction.OPEN,
|
||||
modal=True, parent=window,
|
||||
buttons=("Cancel",
|
||||
Gtk.ResponseType.CANCEL,
|
||||
"Open",
|
||||
Gtk.ResponseType.ACCEPT))
|
||||
dialog.set_do_overwrite_confirmation(False)
|
||||
result = dialog.run()
|
||||
if result == Gtk.ResponseType.ACCEPT:
|
||||
self.save_calendar_list()
|
||||
self.filename = dialog.get_filename()
|
||||
self.events = []
|
||||
self. load_calendar_list(self.filename)
|
||||
calendar = self.builder.get_object("calendar")
|
||||
self.on_day_changed(calendar)
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
def on_add_clicked(self, button):
|
||||
dialog = self.builder.get_object("dialog")
|
||||
name = self.builder.get_object("event_name")
|
||||
location = self.builder.get_object("location")
|
||||
start = self.builder.get_object("start_time")
|
||||
end = self.builder.get_object("end_time")
|
||||
# Reset the event name and location since the dialog is reused.
|
||||
name.set_text("")
|
||||
location.set_text("")
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.APPLY:
|
||||
# Create a new event with the entered name, location and start time.
|
||||
calendar = self.builder.get_object("calendar")
|
||||
(year, month, day) = calendar.get_date()
|
||||
calendar = self.builder.get_object("calendar")
|
||||
(year, month, day) = calendar.get_date()
|
||||
event = Event()
|
||||
event.day = str(day)
|
||||
event.month = str(month+1)
|
||||
event.year = str(year)
|
||||
event.name = name.get_text()
|
||||
event.location = location.get_text()
|
||||
event.start = start.get_active_text()
|
||||
|
||||
# If the start time is "All Day", make the end time an empty string.
|
||||
if event.start == "All Day":
|
||||
event.end = ""
|
||||
else:
|
||||
event.end = end.get_active_text()
|
||||
self.events.append(event)
|
||||
self.save_calendar_list()
|
||||
self.on_day_changed(calendar)
|
||||
dialog.hide()
|
||||
|
||||
|
||||
def on_remove_clicked(self, button):
|
||||
treeview = self.builder.get_object("treeview")
|
||||
store = self.builder.get_object("liststore")
|
||||
selection = treeview.get_selection()
|
||||
(model, iter) = selection.get_selected()
|
||||
if iter == None:
|
||||
return
|
||||
(name, location, time) = store.get(iter, self.NAME, self.LOCATION, self.TIME)
|
||||
words = time.split()
|
||||
if len(words) == 2:
|
||||
# start time was "All Day"
|
||||
start = time
|
||||
end = ""
|
||||
else:
|
||||
start = words[0]
|
||||
end = words[2]
|
||||
for event in self.events:
|
||||
if name == event.name and location == event.location and start == event.start and end == event.end:
|
||||
idx = self.events.index(event)
|
||||
del self.events[idx]
|
||||
self.save_calendar_list()
|
||||
calendar = self.builder.get_object("calendar")
|
||||
self.on_day_changed(calendar)
|
||||
|
||||
|
||||
def on_clear_clicked(self, button):
|
||||
self.events = []
|
||||
calendar = self.builder.get_object("calendar")
|
||||
self.on_day_changed(calendar)
|
||||
|
||||
|
||||
def on_month_changed(self, calendar):
|
||||
calendar = self.builder.get_object("calendar")
|
||||
self.on_day_changed(calendar)
|
||||
|
||||
|
||||
def on_day_changed(self, calendar):
|
||||
treeview = self.builder.get_object("treeview")
|
||||
store = self.builder.get_object("liststore")
|
||||
store.clear()
|
||||
(year, month, day) = calendar.get_date()
|
||||
for event in self.events:
|
||||
if event.end == None:
|
||||
event.end = ""
|
||||
if event.year == str(year) and event.month == str(month+1) and \
|
||||
event.day == str(day):
|
||||
if event.start != "All Day":
|
||||
time = event.start + " to " + event.end
|
||||
else:
|
||||
time = event.start
|
||||
iter = store.append()
|
||||
store.set(iter, (self.NAME, self.LOCATION, self.TIME),
|
||||
(event.name, event.location, time))
|
||||
|
||||
|
||||
def load_calendar_list(self, filename):
|
||||
contenthandler = CalendarContentHandler()
|
||||
xml.sax.parse(filename, contenthandler)
|
||||
self.filename = filename
|
||||
self.events = contenthandler.events
|
||||
calendar = self.builder.get_object("calendar")
|
||||
self.on_day_changed(calendar)
|
||||
|
||||
|
||||
def save_calendar_list(self):
|
||||
f = open(self.filename, 'w')
|
||||
f.write("<calendar>\n")
|
||||
for event in self.events:
|
||||
f.write(" <event>\n")
|
||||
f.write(" <name>" + event.name + "</name>\n")
|
||||
f.write(" <location>" + event.location + "</location>\n")
|
||||
f.write(" <day>" + event.day + "</day>\n")
|
||||
f.write(" <month>" + event.month + "</month>\n")
|
||||
f.write(" <year>" + event.year + "</year>\n")
|
||||
f.write(" <start>" + event.start + "</start>\n")
|
||||
if event.end == None:
|
||||
event.end = ""
|
||||
f.write(" <end>" + event.end + "</end>\n")
|
||||
f.write(" </event>\n")
|
||||
f.write("</calendar>\n")
|
||||
f.close()
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(application_id="org.example.calendar",
|
||||
*args, **kwargs)
|
||||
self.window = None
|
||||
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file("./Calendar.glade")
|
||||
self.window = builder.get_object("window")
|
||||
self.add_window(self.window)
|
||||
self.NAME = 0
|
||||
self.LOCATION = 1
|
||||
self.TIME = 2
|
||||
self.treeview = builder.get_object("treeview")
|
||||
self.config_treeview_columns(builder)
|
||||
sig = SignalHandlers(builder)
|
||||
builder.connect_signals(sig)
|
||||
sig.load_calendar_list("./Calendar_File.xml")
|
||||
self.window.show_all()
|
||||
|
||||
|
||||
def config_treeview_columns(self, builder):
|
||||
renderer = Gtk.CellRendererText()
|
||||
column = Gtk.TreeViewColumn(cell_renderer=renderer, title="Event Name", text=self.NAME)
|
||||
self.treeview.append_column(column)
|
||||
|
||||
renderer = Gtk.CellRendererText()
|
||||
column = Gtk.TreeViewColumn(cell_renderer=renderer, title="Location", text=self.LOCATION)
|
||||
self.treeview.append_column(column)
|
||||
|
||||
renderer = Gtk.CellRendererText()
|
||||
column = Gtk.TreeViewColumn(cell_renderer=renderer, title="Event Time", text=self.TIME)
|
||||
self.treeview.append_column(column)
|
||||
|
||||
store = builder.get_object("liststore")
|
||||
self.treeview.set_model(store)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
11
Integrating/Calendar_File.xml
Normal file
11
Integrating/Calendar_File.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<calendar>
|
||||
<event>
|
||||
<name>Independence Day</name>
|
||||
<location>Everywhere</location>
|
||||
<day>4</day>
|
||||
<month>7</month>
|
||||
<year>2018</year>
|
||||
<start>All Day</start>
|
||||
<end></end>
|
||||
</event>
|
||||
</calendar>
|
507
Integrating/FileBrowser.glade
Normal file
507
Integrating/FileBrowser.glade
Normal file
@@ -0,0 +1,507 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkDialog" id="dialog">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog -vbox1">
|
||||
<property name="name">dialog</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog-action-area">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="name">grid1</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="row_spacing">5</property>
|
||||
<property name="column_spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Name:</property>
|
||||
<property name="xalign">1</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="name">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">File Name</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="hseperator2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="hseperator1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Type:</property>
|
||||
<property name="xalign">1</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Location:</property>
|
||||
<property name="xalign">1</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="type">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">File/Directory</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="name">label3</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Size:</property>
|
||||
<property name="xalign">1</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="size">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">5 KB</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Last Modified:</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="modified">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Day Mth DD HH:MM:SS YYYY</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label7">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Last Accessed:</property>
|
||||
<property name="xalign">1</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="accessed">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Day Mth DD HH:MM:SS YYYY</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="typ">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">File Type</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-7">button1</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<property name="height_request">500</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">File Browser</property>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar" id="toolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="toolbar_style">both</property>
|
||||
<property name="show_arrow">False</property>
|
||||
<property name="icon_size">2</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="back">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Back</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-go-back</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="forward">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Forward</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-go-forward</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="up">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Up</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-go-up</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="refresh">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Refresh</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-refresh</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="home">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Home</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-home</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="delete">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Delete</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-delete</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="info">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Information</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="stock_id">gtk-dialog-info</property>
|
||||
<signal name="clicked" handler="on_info_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label_location">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xpad">5</property>
|
||||
<property name="ypad">5</property>
|
||||
<property name="label" translatable="yes">Current Location:</property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="location">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="go">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<signal name="clicked" handler="on_go_clicked" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-jump-to</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Go</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scdolledwindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStatusbar" id="statusbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
385
Integrating/FileBrowser.py
Normal file
385
Integrating/FileBrowser.py
Normal file
@@ -0,0 +1,385 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import os, time
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, GdkPixbuf, GObject
|
||||
|
||||
ICON = 0
|
||||
FILENAME = 1
|
||||
SIZE = 2
|
||||
MODIFIED = 3
|
||||
|
||||
size_type = ["B", "KiB", "MiB", "GiB"]
|
||||
|
||||
class History():
|
||||
|
||||
def __init__(self):
|
||||
self.stack = []
|
||||
self.pos = -1
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(application_id="org.example.myapp", *args,
|
||||
**kwargs)
|
||||
self.window = None
|
||||
self.dialog = None
|
||||
self.builder = None
|
||||
self.treeview = None
|
||||
self.history = History()
|
||||
self.statusbar = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.builder = Gtk.Builder()
|
||||
self.builder.add_from_file("./FileBrowser.glade")
|
||||
self.window = self.builder.get_object("window")
|
||||
self.treeview = self.builder.get_object("treeview")
|
||||
|
||||
# Glade does not allow us to add non-GTK items to the user data
|
||||
# for connection. Also, the Gtk.Builder widget is absent from
|
||||
# Glade as well. Therefore we have to make our connections to
|
||||
# the signal handlers manually.
|
||||
info = self.builder.get_object("info")
|
||||
info.connect_after("clicked", self.on_info_clicked, self.builder,
|
||||
self.history)
|
||||
|
||||
self.treeview.connect_after("row_activated", self.on_row_activated,
|
||||
self.builder, self.history)
|
||||
|
||||
back = self.builder.get_object("back")
|
||||
back.connect_after("clicked", self.on_back_clicked, self.builder,
|
||||
self.history)
|
||||
|
||||
forward = self.builder.get_object("forward")
|
||||
forward.connect_after("clicked", self.on_forward_clicked, self.builder,
|
||||
self.history)
|
||||
|
||||
up = self.builder.get_object("up")
|
||||
up.connect_after("clicked", self.on_up_clicked, self.builder,
|
||||
self.history)
|
||||
|
||||
home = self.builder.get_object("home")
|
||||
home.connect_after("clicked", self.on_home_clicked, self.builder,
|
||||
self.history)
|
||||
|
||||
delete = self.builder.get_object("delete")
|
||||
delete.connect_after("clicked", self.on_delete_clicked, self.builder)
|
||||
|
||||
go = self.builder.get_object("go")
|
||||
go.connect_after("clicked", self.on_go_clicked, self.builder,
|
||||
self.history)
|
||||
|
||||
entry = self.builder.get_object("location")
|
||||
entry.connect_after("activate", self.on_location_activate, self.builder,
|
||||
self.history)
|
||||
|
||||
refresh = self.builder.get_object("refresh")
|
||||
refresh.connect_after("clicked", self.on_refresh_clicked, self.builder)
|
||||
|
||||
self.setup_tree_view(self.treeview)
|
||||
self.setup_tree_model(self.treeview)
|
||||
self.add_window(self.window)
|
||||
self.window.show_all()
|
||||
|
||||
def setup_tree_view(self, treeview):
|
||||
# Create a tree view column with an icon and file name.
|
||||
column = Gtk.TreeViewColumn.new()
|
||||
column.set_title("File Name")
|
||||
|
||||
renderer = Gtk.CellRendererPixbuf.new()
|
||||
column.pack_start(renderer, False)
|
||||
column.set_attributes(renderer, pixbuf=ICON)
|
||||
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column.pack_start(renderer, True)
|
||||
column.set_attributes(renderer, text=FILENAME)
|
||||
|
||||
treeview.append_column(column)
|
||||
|
||||
# Insert a second tree view column that displays the file size.
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn.new()
|
||||
column.set_title("Size")
|
||||
column.pack_start(renderer, True)
|
||||
column.set_attributes(renderer, text=SIZE)
|
||||
treeview.append_column(column)
|
||||
|
||||
# Insert a third tree view column that displays the last modified time/date.
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn.new()
|
||||
column.set_title("Last Modified")
|
||||
column.pack_start(renderer, True)
|
||||
column.set_attributes(renderer, text=MODIFIED)
|
||||
treeview.append_column(column)
|
||||
|
||||
def setup_tree_model(self, treeview):
|
||||
store = Gtk.ListStore.new((GdkPixbuf.Pixbuf, GObject.TYPE_STRING,
|
||||
GObject.TYPE_STRING, GObject.TYPE_STRING))
|
||||
treeview.set_model(store)
|
||||
self.populate_tree_model(self.builder)
|
||||
|
||||
def populate_tree_model(self, builder):
|
||||
treeview = builder.get_object("treeview")
|
||||
total_size = 0
|
||||
items = 0
|
||||
store = treeview.get_model()
|
||||
store.clear()
|
||||
location = os.getcwd()
|
||||
|
||||
# If the current location is not the root directory, add the '..' entry.
|
||||
if len(location) > 1:
|
||||
icon_theme = Gtk.IconTheme.get_default()
|
||||
icon = icon_theme.load_icon("folder", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
iter = store.append()
|
||||
store.set(iter, (ICON, FILENAME), (icon, ".."))
|
||||
|
||||
# Return if the path does not exist.
|
||||
if not os.path.isdir(location):
|
||||
self.file_manager_error("The path %s does not exist!" % (location,), builder)
|
||||
|
||||
# Display the new location in the address bar.
|
||||
entry = builder.get_object("location")
|
||||
entry.set_text(location)
|
||||
|
||||
# Add each file to the list along with the file size and modified date.
|
||||
pixbuf_dir = icon
|
||||
pixbuf_file = icon_theme.load_icon("text-x-generic", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
files = os.listdir(location)
|
||||
for file in files:
|
||||
fn = location + "/" + file
|
||||
st = os.stat(fn)
|
||||
if st:
|
||||
# Calculate the file size and order of magnitude.
|
||||
i = 0
|
||||
size = st.st_size
|
||||
total_size = size;
|
||||
while size >= 1024.0:
|
||||
size = size / 1024.0
|
||||
i += 1
|
||||
|
||||
# Create strings for the file size and last modified date.
|
||||
filesize = "%.1f %s" % (size, size_type[i])
|
||||
modified = time.ctime(st.st_mtime)
|
||||
|
||||
# Add the file and its properties as a new tree view row.
|
||||
iter = store.append()
|
||||
|
||||
if os.path.isdir(fn):
|
||||
store.set(iter, (ICON, FILENAME, SIZE, MODIFIED),
|
||||
(pixbuf_dir, file, filesize, modified))
|
||||
else:
|
||||
store.set(iter, (ICON, FILENAME, SIZE, MODIFIED),
|
||||
(pixbuf_file, file, filesize, modified))
|
||||
items += 1
|
||||
|
||||
# Calculate the total size of the directory content.
|
||||
i = 0
|
||||
while total_size >= 1024.0:
|
||||
total_size = total_size / 1024.0
|
||||
i += 1
|
||||
|
||||
# Add the number of items and the total size of the directory content
|
||||
# to the status bar.
|
||||
statusbar = builder.get_object("statusbar")
|
||||
message = "%d items, Total Size: %.1f %s" % (items,
|
||||
total_size, size_type[i])
|
||||
context_id = statusbar.get_context_id("FileBrowser")
|
||||
statusbar.pop(context_id)
|
||||
statusbar.push(context_id, message)
|
||||
|
||||
def file_manager_error(self, message, builder):
|
||||
window = builder.get_object("window")
|
||||
dialog = builder.get_object("dialog")
|
||||
dialog = Gtk.MessageDialog(parent=window, modal=True,
|
||||
message_type=Gtk.MessageType.ERROR,
|
||||
buttons=("OK", Gtk.ResponseType.OK),
|
||||
title="File Manager Error")
|
||||
dialog.format_secondary_text(message)
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
def on_info_clicked(self, button, builder, history):
|
||||
treeview = builder.get_object("treeview")
|
||||
dialog = builder.get_object("dialog")
|
||||
selection = treeview.get_selection()
|
||||
|
||||
(model, iter) = selection.get_selected()
|
||||
if iter:
|
||||
name = builder.get_object("name")
|
||||
loc = builder.get_object("location")
|
||||
type = builder.get_object("type")
|
||||
size = builder.get_object("size")
|
||||
mod = builder.get_object("modified")
|
||||
accessed = builder.get_object("accessed")
|
||||
(file,) = model.get(iter, FILENAME)
|
||||
|
||||
# Set the file name, location and whether it is a file or directory.
|
||||
location = os.getcwd()
|
||||
name.set_text(file)
|
||||
loc.set_text(location)
|
||||
file = location + "/" + file
|
||||
if os.path.isdir(file):
|
||||
type.set_text("Directory")
|
||||
else:
|
||||
type.set_text("File")
|
||||
|
||||
# Set the file size, last modified date and last accessed date.
|
||||
st = os.stat(file)
|
||||
if st:
|
||||
i = 0
|
||||
file_size = st.st_size
|
||||
while file_size >= 1024.0:
|
||||
file_size = file_size / 1024.0
|
||||
i += 1
|
||||
|
||||
modified = time.ctime(st.st_mtime)
|
||||
access = time.ctime(st.st_atime)
|
||||
mod.set_text(modified)
|
||||
accessed.set_text(access)
|
||||
size.set_text("%.1f %s" % (file_size, size_type[i]))
|
||||
|
||||
dialog.run()
|
||||
dialog.hide()
|
||||
|
||||
def on_back_clicked(self, button, builder, history):
|
||||
if len(history.stack) > 0:
|
||||
if history.pos > -1:
|
||||
previous_loc = history.stack[history.pos]
|
||||
history.pos -= 1
|
||||
os.chdir(previous_loc)
|
||||
self.populate_tree_model(builder)
|
||||
|
||||
def on_forward_clicked(self, button, builder, history ):
|
||||
if history.pos < len(history.stack) - 1:
|
||||
history.pos += 1
|
||||
next_loc = history.stack[history.pos]
|
||||
os.chdir(next_loc)
|
||||
self.populate_tree_model(builder)
|
||||
|
||||
def on_up_clicked(self, button, builder, history):
|
||||
os.chdir("..")
|
||||
location = os.getcwd()
|
||||
|
||||
entry = builder.get_object("location")
|
||||
entry.set_text(location)
|
||||
go = builder.get_object("go")
|
||||
self.on_go_clicked(go, builder, history)
|
||||
|
||||
def on_refresh_clicked(self, button, builder):
|
||||
self.populate_tree_model(builder)
|
||||
|
||||
def on_home_clicked(self, button, builder, history):
|
||||
go = builder.get_object("go")
|
||||
entry = builder.get_object("location")
|
||||
entry.set_text(os.getenv("HOME"))
|
||||
self.on_go_clicked(go, builder, history)
|
||||
|
||||
def on_delete_clicked(self, button, builder):
|
||||
entry = builder.get_object("location")
|
||||
treeview = builder.get_object("treeview")
|
||||
window = builder.get_object("window")
|
||||
location = os.getcwd()
|
||||
|
||||
# If there is a selected file, delete it if the user approves.
|
||||
selection = treeview.get_selection()
|
||||
(model, iter) = selection.get_selected()
|
||||
if iter:
|
||||
(file,) = model.get(iter, FILENAME)
|
||||
if file == "..":
|
||||
self.file_manager_error("You cannot remove the '..' directory!",
|
||||
builder)
|
||||
return
|
||||
|
||||
entry.set_text(location)
|
||||
rmlocation = location + "/" + file
|
||||
|
||||
# Ask the user if it is okay to remove the file or folder.
|
||||
msg = "Do you really want to delete %s?" % file
|
||||
dialog = Gtk.MessageDialog(parent=window, modal=True,
|
||||
message_type=Gtk.MessageType.QUESTION,
|
||||
buttons=("Yes", Gtk.ResponseType.YES,
|
||||
"No", Gtk.ResponseType.NO),
|
||||
text=msg)
|
||||
|
||||
# If the user approves, remove the file or report ane error.
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.YES:
|
||||
if os.path.isdir(rmlocation):
|
||||
try:
|
||||
shutil.rmtree(rmlocation)
|
||||
except Exception as e:
|
||||
self.file_manager_error(
|
||||
"The file or folder could not be removed!", builder)
|
||||
self.populate_tree_model(builder)
|
||||
else:
|
||||
try:
|
||||
os.remove(rmlocation)
|
||||
except Exception as e:
|
||||
self.file_manager_error(
|
||||
"The file or folder could not be removed!", builder)
|
||||
self.populate_tree_model(builder)
|
||||
dialog.destroy()
|
||||
|
||||
def on_go_clicked(self, button, builder, history):
|
||||
treeview = builder.get_object("treeview")
|
||||
entry = builder.get_object("location")
|
||||
location = entry.get_text()
|
||||
|
||||
# If the directory exists, visit the entered location.
|
||||
if os.path.isdir(location):
|
||||
self.store_history(history)
|
||||
os.chdir(location)
|
||||
self.populate_tree_model(builder)
|
||||
else:
|
||||
self.file_manager_error("The location does not exist!", builder)
|
||||
|
||||
def on_location_activate(self, button, builder, history):
|
||||
go = builder.get_object("go")
|
||||
self.on_go_clicked(go, builder, history)
|
||||
|
||||
def on_row_activated(self, treeview, path, column, builder, history):
|
||||
treeview = builder.get_object("treeview")
|
||||
model = treeview.get_model()
|
||||
iter = model.get_iter(path)
|
||||
if iter:
|
||||
(file,) = model.get(iter, FILENAME)
|
||||
|
||||
# Move to the parent directory.
|
||||
if file == "..":
|
||||
self.store_history(history)
|
||||
os.chdir("..")
|
||||
self.populate_tree_model(builder)
|
||||
# Move to the chosen directory or show more information about the file.
|
||||
else:
|
||||
location = os.getcwd() + "/" + file
|
||||
if os.path.isdir(location):
|
||||
self.store_history(history)
|
||||
os.chdir(location)
|
||||
self.populate_tree_model(builder)
|
||||
else:
|
||||
info = builder.get_object("info")
|
||||
self.on_info_clicked(info, builder, history)
|
||||
|
||||
def store_history(self, history):
|
||||
location = os.getcwd()
|
||||
history.stack.append(location)
|
||||
history.pos = len(history.stack) - 1
|
||||
|
||||
def pop_history(self, history):
|
||||
if len(history.stack) > 0:
|
||||
history.stack.pop()
|
||||
if history.stack.pos > len(history.stack) - 1:
|
||||
history.pos = len(history.stack) - 1
|
||||
else:
|
||||
history.pos -= 1
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
234
Integrating/Ping.glade
Normal file
234
Integrating/Ping.glade
Normal file
@@ -0,0 +1,234 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
<property name="page_size">10</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustment1">
|
||||
<property name="upper">100</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">10</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">network-transmit</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">process-stop</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">window-close</property>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">7</property>
|
||||
<property name="default_width">450</property>
|
||||
<property name="default_height">400</property>
|
||||
<property name="show_menubar">False</property>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="row_spacing">7</property>
|
||||
<property name="column_spacing">7</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Address: </property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Pings: </property>
|
||||
<property name="xalign">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="address">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="width">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="requests_all">
|
||||
<property name="label" translatable="yes">Continuous requests</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">requests_num</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">4</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">requests</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="requests">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">adjustment1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="requests_num">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">requests_all</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="output">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="ping">
|
||||
<property name="label" translatable="yes">Ping</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image1</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_ping_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="stop">
|
||||
<property name="label" translatable="yes">Stop</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image2</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_stop_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="close">
|
||||
<property name="label" translatable="yes">Close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image3</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_window_close" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
201
Integrating/Ping.py
Normal file
201
Integrating/Ping.py
Normal file
@@ -0,0 +1,201 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import os, signal
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, GLib, GObject
|
||||
|
||||
class SignalHandlers():
|
||||
|
||||
def __init__(self, builder):
|
||||
self.builder = builder
|
||||
self.SEQ = 0
|
||||
self.ADDRESS = 1
|
||||
self.TTL = 2
|
||||
self.TIME = 3
|
||||
self.UNITS = 4
|
||||
self.channel = None
|
||||
self.pid = None
|
||||
self.window = builder.get_object("window")
|
||||
self.treeview = builder.get_object("output")
|
||||
self.cpid = None
|
||||
self.setup_tree_view(self.treeview)
|
||||
|
||||
def on_ping_clicked(self, button):
|
||||
requests = self.builder.get_object("requests")
|
||||
radio = self.builder.get_object("requests_num")
|
||||
address = self.builder.get_object("address")
|
||||
treeview = self.treeview
|
||||
|
||||
# Create a new tree model with five columns for ping output.
|
||||
store = Gtk.ListStore.new((str, str, str, str, str))
|
||||
self.treeview.set_model(store)
|
||||
|
||||
# Retrieve the current ping parameters entered by the user.
|
||||
num = requests.get_value_as_int()
|
||||
location = address.get_text()
|
||||
|
||||
# Return if an address was not entered into the GtkEntry widget.
|
||||
if len(location) == 0:
|
||||
return
|
||||
# Otherwise, build the command based upon the user's preferences.
|
||||
elif radio.get_active():
|
||||
if num == 0:
|
||||
return
|
||||
command = "ping " + location + " -c " + str(num)
|
||||
else:
|
||||
command = "ping " + location
|
||||
|
||||
# Parse the command and launch the process, monitoring standard output.
|
||||
(bool, argvp) = GLib.shell_parse_argv(command)
|
||||
if bool:
|
||||
(ret, self.cpid, fin, fout, ferr) = GLib.spawn_async_with_pipes(None,
|
||||
argvp, None, GLib.SpawnFlags.SEARCH_PATH,
|
||||
None, None)
|
||||
if not ret:
|
||||
print("The 'ping' instruction has failed!")
|
||||
else:
|
||||
# Disable the Ping button and enable the Stop button.
|
||||
stop = self.builder.get_object("stop")
|
||||
stop.set_sensitive(True)
|
||||
ping = self.builder.get_object("ping")
|
||||
ping.set_sensitive(False)
|
||||
|
||||
# Create a new IO channel and monitor it for data to read.
|
||||
channel = GLib.IOChannel.unix_new(fout)
|
||||
channel.add_watch(GLib.IOCondition.IN | GLib.IOCondition.ERR |
|
||||
GLib.IOCondition.HUP, self.read_output, None)
|
||||
|
||||
def on_stop_clicked(self, button):
|
||||
stop = self.builder.get_object("stop")
|
||||
stop.set_sensitive(False)
|
||||
ping = self.builder.get_object("ping")
|
||||
ping.set_sensitive(True)
|
||||
|
||||
os.kill(self.cpid, signal.SIGINT)
|
||||
self.cpid = None
|
||||
|
||||
def on_window_close(self, button):
|
||||
self.window.destroy()
|
||||
|
||||
def setup_tree_view(self, treeview):
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn(title="Seq", cell_renderer=renderer,
|
||||
text=self.SEQ)
|
||||
treeview.append_column(column)
|
||||
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn(title="Address", cell_renderer=renderer,
|
||||
text=self.ADDRESS)
|
||||
treeview.append_column(column)
|
||||
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn(title="TTL", cell_renderer=renderer,
|
||||
text=self.TTL)
|
||||
treeview.append_column(column)
|
||||
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn(title="Time", cell_renderer=renderer,
|
||||
text=self.TIME)
|
||||
treeview.append_column(column)
|
||||
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn(title="Units", cell_renderer=renderer,
|
||||
text=self.UNITS)
|
||||
treeview.append_column(column)
|
||||
|
||||
|
||||
def read_output(self, channel, condition, data):
|
||||
# Read the current line of data from the IO channel.
|
||||
errstatus = False
|
||||
try:
|
||||
(status, line, length, term) = channel.read_line()
|
||||
except IOError:
|
||||
print("Error reading IO channel.")
|
||||
errstatus = True
|
||||
|
||||
# If some type of error has occurred, handle it.
|
||||
if errstatus or status != GLib.IOStatus.NORMAL or line == None:
|
||||
print("Error reading IO channel.")
|
||||
|
||||
# Disable the stop button and enable the ping button for future action.
|
||||
stop = self.builder.get_object("stop")
|
||||
stop.set_sensitive(False)
|
||||
ping = self.builder.get_object("ping")
|
||||
ping.set_sensitive(True)
|
||||
|
||||
if channel != None:
|
||||
channel.shutdown(True)
|
||||
channel = None
|
||||
|
||||
return False
|
||||
|
||||
# Parse the line if an error has not occurred.
|
||||
self.parse_output(line)
|
||||
|
||||
return True
|
||||
|
||||
def parse_output(self, buffer):
|
||||
# Load the list store, split the string into lines and create a pointer.
|
||||
store = self.treeview.get_model()
|
||||
lines = buffer.splitlines()
|
||||
|
||||
# Loop through each of the lines, parsing its content.
|
||||
for line in lines:
|
||||
# If this is an empty string, move to the next string.
|
||||
if line == "":
|
||||
continue
|
||||
# Parse the line if it contains information about the current ping.
|
||||
elif line.find("64 bytes") >= 0:
|
||||
# Extract the IP address of the computer you are pinging.
|
||||
result = line.split("from ")
|
||||
result = result[1].split(':')
|
||||
address = result[0]
|
||||
|
||||
# Extract the current ping count from the output.
|
||||
result = line.split("seq=")
|
||||
result = result[1].split(" ")
|
||||
seq = result[0]
|
||||
|
||||
# Extract the IP's "Time To Live" from the output.
|
||||
result = line.split("ttl=")
|
||||
result = result[1].split(" ")
|
||||
ttl = result[0]
|
||||
|
||||
# Extract the time it took for this ping operation from the output.
|
||||
result = line.split("time=")
|
||||
result = result[1].split(" ")
|
||||
time = result[0]
|
||||
|
||||
# Extrace the time units from the output.
|
||||
result = result[1].split(" ")
|
||||
units = result[0]
|
||||
|
||||
# Append the information for the current ping operation.
|
||||
iter = store.append ();
|
||||
store.set (iter, (self.SEQ, self.ADDRESS, self.TTL, self.TIME,
|
||||
self.UNITS),
|
||||
(seq, address, ttl, time, units))
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file("./Ping.glade")
|
||||
self.window = builder.get_object("window")
|
||||
builder.connect_signals(SignalHandlers(builder))
|
||||
self.add_window(self.window)
|
||||
self.window.show_all()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
||||
|
27
LICENSE.txt
Normal file
27
LICENSE.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
Freeware License, some rights reserved
|
||||
|
||||
Copyright (c) 2019 W. David Ashley and Andrew Krause
|
||||
|
||||
Permission is hereby granted, free of charge, to anyone obtaining a copy
|
||||
of this software and associated documentation files (the "Software"),
|
||||
to work with the Software within the limits of freeware distribution and fair use.
|
||||
This includes the rights to use, copy, and modify the Software for personal use.
|
||||
Users are also allowed and encouraged to submit corrections and modifications
|
||||
to the Software for the benefit of other users.
|
||||
|
||||
It is not allowed to reuse, modify, or redistribute the Software for
|
||||
commercial use in any way, or for a user’s educational materials such as books
|
||||
or blog articles without prior permission from the copyright holder.
|
||||
|
||||
The above copyright notice and this permission notice need to be included
|
||||
in all copies or substantial portions of the software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
100
Menus_And_Toolbars/Exercise_1.py
Normal file
100
Menus_And_Toolbars/Exercise_1.py
Normal file
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, -1)
|
||||
# Create all of the necessary widgets and initialize the pop-up menu.
|
||||
menu = Gtk.Menu.new()
|
||||
eventbox = Gtk.EventBox.new()
|
||||
progress = Gtk.ProgressBar.new()
|
||||
progress.set_text("Nothing Yet Happened")
|
||||
progress.set_show_text(True)
|
||||
self.create_popup_menu(menu, progress)
|
||||
progress.set_pulse_step(0.05)
|
||||
eventbox.set_above_child(False)
|
||||
eventbox.connect("button_press_event", self.button_press_event, menu)
|
||||
eventbox.add(progress)
|
||||
eventbox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
|
||||
eventbox.realize()
|
||||
self.hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
self.hbox.pack_start(eventbox, False, False, 5)
|
||||
self.add(self.hbox)
|
||||
|
||||
def create_popup_menu(self, menu, progress):
|
||||
pulse = Gtk.MenuItem.new_with_label("Pulse Progress")
|
||||
fill = Gtk.MenuItem.new_with_label("Set as Complete")
|
||||
clear = Gtk.MenuItem.new_with_label("Clear Progress")
|
||||
separator = Gtk.SeparatorMenuItem.new()
|
||||
pulse.connect("activate", self.pulse_activated, progress)
|
||||
fill.connect("activate", self.fill_activated, progress)
|
||||
clear.connect("activate", self.clear_activated, progress)
|
||||
menu.append(pulse)
|
||||
menu.append(separator)
|
||||
menu.append(fill)
|
||||
menu.append(clear)
|
||||
menu.attach_to_widget(progress, None)
|
||||
menu.show_all()
|
||||
|
||||
def button_press_event(self, eventbox, event, menu):
|
||||
pass
|
||||
|
||||
def pulse_activated(self, item, progress):
|
||||
pass
|
||||
|
||||
def fill_activated(self, item, progress):
|
||||
pass
|
||||
|
||||
def clear_activated(self, item, progress):
|
||||
pass
|
||||
|
||||
def on_cutstandard(self, widget):
|
||||
pass
|
||||
|
||||
def on_copystandard(self, widget):
|
||||
pass
|
||||
|
||||
def on_pastestandard(self, widget):
|
||||
pass
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Exercise 1")
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file("./Exercise_1_Toolbar.xml")
|
||||
builder.connect_signals(self.window)
|
||||
toolbar = builder.get_object("toolbar")
|
||||
toolbar.set_orientation(Gtk.Orientation.VERTICAL)
|
||||
self.window.hbox.pack_end(toolbar, True, False, 1)
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
def on_newstandard(self, widget):
|
||||
pass
|
||||
|
||||
def on_openstandard(self, widget):
|
||||
pass
|
||||
|
||||
def on_savestandard(self, widget):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
92
Menus_And_Toolbars/Exercise_1_Toolbar.xml
Normal file
92
Menus_And_Toolbars/Exercise_1_Toolbar.xml
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<interface>
|
||||
<requires lib='gtk+' version='3.4'/>
|
||||
<object class='GtkToolbar' id='toolbar'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<child>
|
||||
<object class='GtkToolButton' id='toolbutton_new'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<property name='tooltip_text' translatable='yes'>New Standard</property>
|
||||
<property name='action_name'>app.on_newstandard</property>
|
||||
<property name='icon_name'>document-new</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name='expand'>False</property>
|
||||
<property name='homogeneous'>True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class='GtkToolButton' id='toolbutton_open'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<property name='tooltip_text' translatable='yes'>Open Standard</property>
|
||||
<property name='action_name'>app.on_openstandard</property>
|
||||
<property name='icon_name'>document-open</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name='expand'>False</property>
|
||||
<property name='homogeneous'>True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class='GtkToolButton' id='toolbutton_save'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<property name='tooltip_text' translatable='yes'>Save Standard</property>
|
||||
<property name='action_name'>app.on_savestandard</property>
|
||||
<property name='icon_name'>document-save</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name='expand'>False</property>
|
||||
<property name='homogeneous'>True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class='GtkSeparatorToolItem' id='toolbutton_separator'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class='GtkToolButton' id='toolbutton_cut'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<property name='tooltip_text' translatable='yes'>Cut Standard</property>
|
||||
<property name='action_name'>win.on_cutstandard</property>
|
||||
<property name='icon_name'>edit-cut</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name='expand'>False</property>
|
||||
<property name='homogeneous'>True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class='GtkToolButton' id='toolbutton_copy'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<property name='tooltip_text' translatable='yes'>Copy Standard</property>
|
||||
<property name='action_name'>win.on_copystandard</property>
|
||||
<property name='icon_name'>edit-copy</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name='expand'>False</property>
|
||||
<property name='homogeneous'>True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class='GtkToolButton' id='toolbutton_paste'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<property name='tooltip_text' translatable='yes'>Paste Standard</property>
|
||||
<property name='action_name'>win.on_pastestandard</property>
|
||||
<property name='icon_name'>edit-paste</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name='expand'>False</property>
|
||||
<property name='homogeneous'>True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
94
Menus_And_Toolbars/Exercise_2.py
Normal file
94
Menus_And_Toolbars/Exercise_2.py
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, -1)
|
||||
# Create all of the necessary widgets and initialize the pop-up menu.
|
||||
menu = Gtk.Menu.new()
|
||||
eventbox = Gtk.EventBox.new()
|
||||
progress = Gtk.ProgressBar.new()
|
||||
progress.set_text("Nothing Yet Happened")
|
||||
progress.set_show_text(True)
|
||||
self.create_popup_menu(menu, progress)
|
||||
progress.set_pulse_step(0.05)
|
||||
eventbox.set_above_child(False)
|
||||
eventbox.connect("button_press_event", self.button_press_event, menu)
|
||||
eventbox.add(progress)
|
||||
self.add(eventbox)
|
||||
eventbox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
|
||||
eventbox.realize()
|
||||
|
||||
def create_popup_menu(self, menu, progress):
|
||||
pulse = Gtk.MenuItem.new_with_label("Pulse Progress")
|
||||
fill = Gtk.MenuItem.new_with_label("Set as Complete")
|
||||
clear = Gtk.MenuItem.new_with_label("Clear Progress")
|
||||
separator = Gtk.SeparatorMenuItem.new()
|
||||
pulse.connect("activate", self.pulse_activated, progress)
|
||||
fill.connect("activate", self.fill_activated, progress)
|
||||
clear.connect("activate", self.clear_activated, progress)
|
||||
menu.append(pulse)
|
||||
menu.append(separator)
|
||||
menu.append(fill)
|
||||
menu.append(clear)
|
||||
menu.attach_to_widget(progress, None)
|
||||
menu.show_all()
|
||||
|
||||
def button_press_event(self, eventbox, event, menu):
|
||||
pass
|
||||
|
||||
def pulse_activated(self, item, progress):
|
||||
pass
|
||||
|
||||
def fill_activated(self, item, progress):
|
||||
pass
|
||||
|
||||
def clear_activated(self, item, progress):
|
||||
pass
|
||||
|
||||
def on_menu_cut(self, menuitem):
|
||||
pass
|
||||
|
||||
def on_menu_copy(self, menuitem):
|
||||
pass
|
||||
|
||||
def on_menu_paste(self, menuitem):
|
||||
pass
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Exercise 2")
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file("./Exercise_2_Menubar.xml")
|
||||
self.set_menubar(builder.get_object("menubar"))
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
def on_menu_new(self, menuitem):
|
||||
pass
|
||||
|
||||
def on_menu_open(self, menuitem):
|
||||
pass
|
||||
|
||||
def on_menu_save(self, menuitem):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
91
Menus_And_Toolbars/Exercise_2_Menubar.xml
Normal file
91
Menus_And_Toolbars/Exercise_2_Menubar.xml
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkMenuBar" id='menubar'>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem">
|
||||
<property name="label">gtk-new</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="app.on_menu_new" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem">
|
||||
<property name="label">gtk-open</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="app.on_menu_open" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem">
|
||||
<property name="label">gtk-save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="app.on_menu_save" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">_Edit</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem">
|
||||
<property name="label">gtk-cut</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="win.on_menu_cut" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem">
|
||||
<property name="label">gtk-copy</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="win.on_menu_copy" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem">
|
||||
<property name="label">gtk-paste</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="win.on_menu_paste" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
49
Menus_And_Toolbars/MenuAndToolbar.py
Normal file
49
Menus_And_Toolbars/MenuAndToolbar.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def change_label(self):
|
||||
pass
|
||||
|
||||
def maximize(self):
|
||||
pass
|
||||
|
||||
def about(self):
|
||||
pass
|
||||
|
||||
def quit(self):
|
||||
self.destroy()
|
||||
|
||||
def newstandard(self):
|
||||
pass
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Hello World!")
|
||||
builder = Gtk.Builder()
|
||||
builder.add_from_file("./Menu_XML_File.ui")
|
||||
builder.add_from_file("./Toolbar_UI_File.xml")
|
||||
builder.connect_signals(self.window)
|
||||
self.set_menubar(builder.get_object("menubar"))
|
||||
self.window.add(builder.get_object("toolbar"))
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
8
Menus_And_Toolbars/MenuToolButton.py
Normal file
8
Menus_And_Toolbars/MenuToolButton.py
Normal file
@@ -0,0 +1,8 @@
|
||||
recent = Gtk.Menu.new()
|
||||
# Add a number of menu items where each corresponds to one recent file.
|
||||
icon_theme = Gtk.IconTheme.get_default()
|
||||
icon = icon_theme.load_icon("document-open", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
image = Gtk.Image.new_from_pixbuf(icon)
|
||||
open = Gtk.MenuToolButton.new(image, label)
|
||||
open.set_menu(recent)
|
17
Menus_And_Toolbars/Menu_XML_File.ui
Normal file
17
Menus_And_Toolbars/Menu_XML_File.ui
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="menubar">
|
||||
<submenu>
|
||||
<attribute name="label">File</attribute>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label">Edit</attribute>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label">Choices</attribute>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label">Help</attribute>
|
||||
</submenu>
|
||||
</menu>
|
||||
</interface>
|
15
Menus_And_Toolbars/Popup_UI_File.xml
Normal file
15
Menus_And_Toolbars/Popup_UI_File.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<interface>
|
||||
<menu id="app-menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label">About</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label">Quit</attribute>
|
||||
<attribute name="action">app.quit</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
61
Menus_And_Toolbars/SimpleMenuBar.py
Normal file
61
Menus_And_Toolbars/SimpleMenuBar.py
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_size_request(250, -1)
|
||||
menubar = Gtk.MenuBar.new()
|
||||
file = Gtk.MenuItem.new_with_label("File")
|
||||
edit = Gtk.MenuItem.new_with_label("Edit")
|
||||
help = Gtk.MenuItem.new_with_label("Help")
|
||||
filemenu = Gtk.Menu.new()
|
||||
editmenu = Gtk.Menu.new()
|
||||
helpmenu = Gtk.Menu.new()
|
||||
file.set_submenu(filemenu)
|
||||
edit.set_submenu(editmenu)
|
||||
help.set_submenu(helpmenu)
|
||||
menubar.append(file)
|
||||
menubar.append(edit)
|
||||
menubar.append(help)
|
||||
# Create the File menu content.
|
||||
new = Gtk.MenuItem.new_with_label("New")
|
||||
open = Gtk.MenuItem.new_with_label("Open")
|
||||
filemenu.append(new)
|
||||
filemenu.append(open)
|
||||
# Create the Edit menu content.
|
||||
cut = Gtk.MenuItem.new_with_label("Cut")
|
||||
copy = Gtk.MenuItem.new_with_label("Copy")
|
||||
paste = Gtk.MenuItem.new_with_label("Paste")
|
||||
editmenu.append(cut)
|
||||
editmenu.append(copy)
|
||||
editmenu.append(paste)
|
||||
# Create the Help menu content.
|
||||
contents = Gtk.MenuItem.new_with_label("Help")
|
||||
about = Gtk.MenuItem.new_with_label("About")
|
||||
helpmenu.append(contents)
|
||||
helpmenu.append(about)
|
||||
self.add(menubar)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Menu Bars")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
71
Menus_And_Toolbars/SimplePopupMenu.py
Normal file
71
Menus_And_Toolbars/SimplePopupMenu.py
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, -1)
|
||||
# Create all of the necessary widgets and initialize the pop-up menu.
|
||||
menu = Gtk.Menu.new()
|
||||
eventbox = Gtk.EventBox.new()
|
||||
progress = Gtk.ProgressBar.new()
|
||||
progress.set_text("Nothing Yet Happened")
|
||||
self.create_popup_menu(menu, progress)
|
||||
progress.set_pulse_step(0.05)
|
||||
eventbox.set_above_child(False)
|
||||
eventbox.connect("button_press_event", self.button_press_event, menu)
|
||||
eventbox.add(progress)
|
||||
self.add(eventbox)
|
||||
eventbox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
|
||||
eventbox.realize()
|
||||
|
||||
def create_popup_menu(self, menu, progress):
|
||||
pulse = Gtk.MenuItem.new_with_label("Pulse Progress")
|
||||
fill = Gtk.MenuItem.new_with_label("Set as Complete")
|
||||
clear = Gtk.MenuItem.new_with_label("Clear Progress")
|
||||
separator = Gtk.SeparatorMenuItem.new()
|
||||
pulse.connect("activate", self.pulse_activated, progress)
|
||||
fill.connect("activate", self.fill_activated, progress)
|
||||
clear.connect("activate", self.clear_activated, progress)
|
||||
menu.append(pulse)
|
||||
menu.append(separator)
|
||||
menu.append(fill)
|
||||
menu.append(clear)
|
||||
menu.attach_to_widget(progress, None)
|
||||
menu.show_all()
|
||||
|
||||
def button_press_event(self, eventbox, event, menu):
|
||||
pass
|
||||
|
||||
def pulse_activated(self, item, progress):
|
||||
pass
|
||||
|
||||
def fill_activated(self, item, progress):
|
||||
pass
|
||||
|
||||
def clear_activated(self, item, progress):
|
||||
pass
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Pop-up Menus")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
77
Menus_And_Toolbars/SimplePopupMenu2.py
Normal file
77
Menus_And_Toolbars/SimplePopupMenu2.py
Normal file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, -1)
|
||||
# Create all of the necessary widgets and initialize the pop-up menu.
|
||||
menu = Gtk.Menu.new()
|
||||
eventbox = Gtk.EventBox.new()
|
||||
progress = Gtk.ProgressBar.new()
|
||||
progress.set_text("Nothing Yet Happened")
|
||||
self.create_popup_menu(menu, progress)
|
||||
progress.set_pulse_step(0.05)
|
||||
eventbox.set_above_child(False)
|
||||
eventbox.connect("button_press_event", self.button_press_event, menu)
|
||||
eventbox.add(progress)
|
||||
self.add(eventbox)
|
||||
eventbox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
|
||||
eventbox.realize()
|
||||
|
||||
def create_popup_menu(self, menu, progress):
|
||||
pulse = Gtk.MenuItem.new_with_label("Pulse Progress")
|
||||
fill = Gtk.MenuItem.new_with_label("Set as Complete")
|
||||
clear = Gtk.MenuItem.new_with_label("Clear Progress")
|
||||
separator = Gtk.SeparatorMenuItem.new()
|
||||
pulse.connect("activate", self.pulse_activated, progress)
|
||||
fill.connect("activate", self.fill_activated, progress)
|
||||
clear.connect("activate", self.clear_activated, progress)
|
||||
menu.append(pulse)
|
||||
menu.append(separator)
|
||||
menu.append(fill)
|
||||
menu.append(clear)
|
||||
menu.attach_to_widget(progress, None)
|
||||
menu.show_all()
|
||||
|
||||
def button_press_event(self, eventbox, event, menu):
|
||||
if event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
menu.popup(None, None, None, None, event.button, event.time)
|
||||
return True
|
||||
return False
|
||||
|
||||
def pulse_activated(self, item, progress):
|
||||
progress.pulse()
|
||||
progress.set_text("Pulse!")
|
||||
|
||||
def fill_activated(self, item, progress):
|
||||
progress.set_fraction(1.0)
|
||||
progress.set_text("One Hundred Percent")
|
||||
|
||||
def clear_activated(self, item, progress):
|
||||
progress.set_fraction(0.0)
|
||||
progress.set_text("Reset to Zero")
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Pop-up Menus")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
88
Menus_And_Toolbars/SimplePopupMenu3.py
Normal file
88
Menus_And_Toolbars/SimplePopupMenu3.py
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, -1)
|
||||
# Create all of the necessary widgets and initialize the pop-up menu.
|
||||
menu = Gtk.Menu.new()
|
||||
eventbox = Gtk.EventBox.new()
|
||||
progress = Gtk.ProgressBar.new()
|
||||
progress.set_text("Nothing Yet Happened")
|
||||
progress.set_show_text(True)
|
||||
self.create_popup_menu(menu, progress)
|
||||
progress.set_pulse_step(0.05)
|
||||
eventbox.set_above_child(False)
|
||||
eventbox.connect("button_press_event", self.button_press_event, menu)
|
||||
eventbox.add(progress)
|
||||
self.add(eventbox)
|
||||
eventbox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
|
||||
eventbox.realize()
|
||||
|
||||
def create_popup_menu(self, menu, progress):
|
||||
group = Gtk.AccelGroup.new()
|
||||
self.add_accel_group(group)
|
||||
menu.set_accel_group(group)
|
||||
pulse = Gtk.MenuItem.new_with_label("Pulse Progress")
|
||||
fill = Gtk.MenuItem.new_with_label("Set as Complete")
|
||||
clear = Gtk.MenuItem.new_with_label("Clear Progress")
|
||||
separator = Gtk.SeparatorMenuItem.new()
|
||||
# Add the necessary keyboard accelerators.
|
||||
pulse.add_accelerator("activate", group, Gdk.KEY_P, Gdk.ModifierType.CONTROL_MASK,
|
||||
Gtk.AccelFlags.VISIBLE)
|
||||
fill.add_accelerator("activate", group, Gdk.KEY_F, Gdk.ModifierType.CONTROL_MASK,
|
||||
Gtk.AccelFlags.VISIBLE)
|
||||
clear.add_accelerator("activate", group, Gdk.KEY_C, Gdk.ModifierType.CONTROL_MASK,
|
||||
Gtk.AccelFlags.VISIBLE)
|
||||
pulse.connect("activate", self.pulse_activated, progress)
|
||||
fill.connect("activate", self.fill_activated, progress)
|
||||
clear.connect("activate", self.clear_activated, progress)
|
||||
menu.append(pulse)
|
||||
menu.append(separator)
|
||||
menu.append(fill)
|
||||
menu.append(clear)
|
||||
menu.attach_to_widget(progress, None)
|
||||
menu.show_all()
|
||||
|
||||
def button_press_event(self, eventbox, event, menu):
|
||||
if event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
menu.popup(None, None, None, None, event.button, event.time)
|
||||
return True
|
||||
return False
|
||||
|
||||
def pulse_activated(self, item, progress):
|
||||
progress.pulse()
|
||||
progress.set_text("Pulse!")
|
||||
|
||||
def fill_activated(self, item, progress):
|
||||
progress.set_fraction(1.0)
|
||||
progress.set_text("One Hundred Percent")
|
||||
|
||||
def clear_activated(self, item, progress):
|
||||
progress.set_fraction(0.0)
|
||||
progress.set_text("Reset to Zero")
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Pop-up Menus")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
111
Menus_And_Toolbars/SimplePopupMenu4.py
Normal file
111
Menus_And_Toolbars/SimplePopupMenu4.py
Normal file
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppMenuItem(Gtk.MenuItem):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
self.__dict__[name] = value
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self.__dict__[name]
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, -1)
|
||||
# Create all of the necessary widgets and initialize the pop-up menu.
|
||||
menu = Gtk.Menu.new()
|
||||
eventbox = Gtk.EventBox.new()
|
||||
progress = Gtk.ProgressBar.new()
|
||||
progress.set_text("Nothing Yet Happened")
|
||||
progress.set_show_text(True)
|
||||
statusbar = Gtk.Statusbar.new()
|
||||
self.create_popup_menu(menu, progress, statusbar)
|
||||
progress.set_pulse_step(0.05)
|
||||
eventbox.set_above_child(False)
|
||||
eventbox.connect("button_press_event", self.button_press_event, menu)
|
||||
eventbox.add(progress)
|
||||
vbox = Gtk.Box.new(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(eventbox, False, True, 0)
|
||||
vbox.pack_start(statusbar, False, True, 0)
|
||||
self.add(vbox)
|
||||
eventbox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
|
||||
eventbox.realize()
|
||||
|
||||
def create_popup_menu(self, menu, progress, statusbar):
|
||||
pulse = AppMenuItem(label="Pulse Progress")
|
||||
fill = AppMenuItem(label="Set as Complete")
|
||||
clear = AppMenuItem(label="Clear Progress")
|
||||
separator = Gtk.SeparatorMenuItem.new()
|
||||
pulse.connect("activate", self.pulse_activated, progress)
|
||||
fill.connect("activate", self.fill_activated, progress)
|
||||
clear.connect("activate", self.clear_activated, progress)
|
||||
# Connect signals to each menu item for status bar messages.
|
||||
pulse.connect("enter-notify-event", self.statusbar_hint, statusbar)
|
||||
pulse.connect("leave-notify-event", self.statusbar_hint, statusbar)
|
||||
fill.connect("enter-notify-event", self.statusbar_hint, statusbar)
|
||||
fill.connect("leave-notify-event", self.statusbar_hint, statusbar)
|
||||
clear.connect("enter-notify-event", self.statusbar_hint, statusbar)
|
||||
clear.connect("leave-notify-event", self.statusbar_hint, statusbar)
|
||||
pulse.__setattr__("menuhint", "Pulse the progress bar one step.")
|
||||
fill.__setattr__("menuhint", "Set the progress bar to 100%.")
|
||||
clear.__setattr__("menuhint", "Clear the progress bar to 0%.")
|
||||
menu.append(pulse)
|
||||
menu.append(separator)
|
||||
menu.append(fill)
|
||||
menu.append(clear)
|
||||
menu.attach_to_widget(progress, None)
|
||||
menu.show_all()
|
||||
|
||||
def button_press_event(self, eventbox, event, menu):
|
||||
if event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS:
|
||||
menu.popup(None, None, None, None, event.button, event.time)
|
||||
return True
|
||||
return False
|
||||
|
||||
def pulse_activated(self, item, progress):
|
||||
progress.pulse()
|
||||
progress.set_text("Pulse!")
|
||||
|
||||
def fill_activated(self, item, progress):
|
||||
progress.set_fraction(1.0)
|
||||
progress.set_text("One Hundred Percent")
|
||||
|
||||
def clear_activated(self, item, progress):
|
||||
progress.set_fraction(0.0)
|
||||
progress.set_text("Reset to Zero")
|
||||
|
||||
def statusbar_hint(self, menuitem, event, statusbar):
|
||||
id = statusbar.get_context_id("MenuItemHints")
|
||||
if event.type == Gdk.EventType.ENTER_NOTIFY:
|
||||
hint = menuitem.__getattr__("menuhint")
|
||||
id = statusbar.push(id, hint)
|
||||
elif event.type == Gdk.EventType.LEAVE_NOTIFY:
|
||||
statusbar.pop(id)
|
||||
return False
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Pop-up Menus")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
80
Menus_And_Toolbars/SimpleToolbar.py
Normal file
80
Menus_And_Toolbars/SimpleToolbar.py
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
toolbar = Gtk.Toolbar.new()
|
||||
entry = Gtk.Entry.new()
|
||||
vbox.pack_start(toolbar, True, False, 0)
|
||||
vbox.pack_start(entry, True, False, 0)
|
||||
self.create_toolbar(toolbar, entry)
|
||||
self.add(vbox)
|
||||
self.set_size_request(310, 75)
|
||||
|
||||
def create_toolbar(self, toolbar, entry):
|
||||
icon_theme = Gtk.IconTheme.get_default()
|
||||
icon = icon_theme.load_icon("edit-cut", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
image = Gtk.Image.new_from_pixbuf(icon)
|
||||
cut = Gtk.ToolButton.new(image, "Cut")
|
||||
icon = icon_theme.load_icon("edit-copy", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
image = Gtk.Image.new_from_pixbuf(icon)
|
||||
copy = Gtk.ToolButton.new(image, "Copy")
|
||||
icon = icon_theme.load_icon("edit-paste", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
image = Gtk.Image.new_from_pixbuf(icon)
|
||||
paste = Gtk.ToolButton.new(image, "Paste")
|
||||
icon = icon_theme.load_icon("edit-select-all", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
image = Gtk.Image.new_from_pixbuf(icon)
|
||||
selectall = Gtk.ToolButton.new(image, "Select All")
|
||||
separator = Gtk.SeparatorToolItem.new()
|
||||
toolbar.set_show_arrow(True)
|
||||
toolbar.set_style(Gtk.ToolbarStyle.BOTH)
|
||||
toolbar.insert(cut, 0)
|
||||
toolbar.insert(copy, 1)
|
||||
toolbar.insert(paste, 2)
|
||||
toolbar.insert(separator, 3)
|
||||
toolbar.insert(selectall, 4)
|
||||
cut.connect("clicked", self.cut_clipboard, entry)
|
||||
copy.connect("clicked", self.copy_clipboard, entry)
|
||||
paste.connect("clicked", self.paste_clipboard, entry)
|
||||
selectall.connect("clicked", self.select_all, entry)
|
||||
|
||||
def cut_clipboard(self, button, entry):
|
||||
entry.cut_clipboard()
|
||||
|
||||
def copy_clipboard(self, button, entry):
|
||||
entry.copy_clipboard()
|
||||
|
||||
def paste_clipboard(self, button, entry):
|
||||
entry.paste_clipboard()
|
||||
|
||||
def select_all(self, button, entry):
|
||||
entry.select_region(0, -1)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Toolbar")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
34
Menus_And_Toolbars/Toolbar_UI_File.xml
Normal file
34
Menus_And_Toolbars/Toolbar_UI_File.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<interface>
|
||||
<requires lib='gtk+' version='3.4'/>
|
||||
<object class='GtkToolbar' id='toolbar'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<child>
|
||||
<object class='GtkToolButton' id='toolbutton_new'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<property name='tooltip_text' translatable='yes'>New Standard</property>
|
||||
<property name='action_name'>app.newstandard</property>
|
||||
<property name='icon_name'>document-new</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name='expand'>False</property>
|
||||
<property name='homogeneous'>True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class='GtkToolButton' id='toolbutton_quit'>
|
||||
<property name='visible'>True</property>
|
||||
<property name='can_focus'>False</property>
|
||||
<property name='tooltip_text' translatable='yes'>Quit</property>
|
||||
<property name='action_name'>app.quit</property>
|
||||
<property name='icon_name'>application-exit</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name='expand'>False</property>
|
||||
<property name='homogeneous'>True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
121
More_Widgets/DrawingArea.py
Normal file
121
More_Widgets/DrawingArea.py
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import cairo
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
SIZE = 30
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_size_request(450, 550)
|
||||
drawingarea = Gtk.DrawingArea()
|
||||
self.add(drawingarea)
|
||||
drawingarea.connect('draw', self.draw)
|
||||
|
||||
def triangle(self, ctx):
|
||||
ctx.move_to(SIZE, 0)
|
||||
ctx.rel_line_to(SIZE, 2 * SIZE)
|
||||
ctx.rel_line_to(-2 * SIZE, 0)
|
||||
ctx.close_path()
|
||||
|
||||
def square(self, ctx):
|
||||
ctx.move_to(0, 0)
|
||||
ctx.rel_line_to(2 * SIZE, 0)
|
||||
ctx.rel_line_to(0, 2 * SIZE)
|
||||
ctx.rel_line_to(-2 * SIZE, 0)
|
||||
ctx.close_path()
|
||||
|
||||
def bowtie(self, ctx):
|
||||
ctx.move_to(0, 0)
|
||||
ctx.rel_line_to(2 * SIZE, 2 * SIZE)
|
||||
ctx.rel_line_to(-2 * SIZE, 0)
|
||||
ctx.rel_line_to(2 * SIZE, -2 * SIZE)
|
||||
ctx.close_path()
|
||||
|
||||
def inf(self, ctx):
|
||||
ctx.move_to(0, SIZE)
|
||||
ctx.rel_curve_to(0, SIZE, SIZE, SIZE, 2 * SIZE, 0)
|
||||
ctx.rel_curve_to(SIZE, -SIZE, 2 * SIZE, -SIZE, 2 * SIZE, 0)
|
||||
ctx.rel_curve_to(0, SIZE, -SIZE, SIZE, -2 * SIZE, 0)
|
||||
ctx.rel_curve_to(-SIZE, -SIZE, -2 * SIZE, -SIZE, -2 * SIZE, 0)
|
||||
ctx.close_path()
|
||||
|
||||
def draw_shapes(self, ctx, x, y, fill):
|
||||
ctx.save()
|
||||
ctx.new_path()
|
||||
ctx.translate(x + SIZE, y + SIZE)
|
||||
self.bowtie(ctx)
|
||||
if fill:
|
||||
ctx.fill()
|
||||
else:
|
||||
ctx.stroke()
|
||||
ctx.new_path()
|
||||
ctx.translate(3 * SIZE, 0)
|
||||
self.square(ctx)
|
||||
if fill:
|
||||
ctx.fill()
|
||||
else:
|
||||
ctx.stroke()
|
||||
ctx.new_path()
|
||||
ctx.translate(3 * SIZE, 0)
|
||||
self.triangle(ctx)
|
||||
if fill:
|
||||
ctx.fill()
|
||||
else:
|
||||
ctx.stroke()
|
||||
ctx.new_path()
|
||||
ctx.translate(3 * SIZE, 0)
|
||||
self.inf(ctx)
|
||||
if fill:
|
||||
ctx.fill()
|
||||
else:
|
||||
ctx.stroke()
|
||||
ctx.restore()
|
||||
|
||||
def fill_shapes(self, ctx, x, y):
|
||||
self.draw_shapes(ctx, x, y, True)
|
||||
|
||||
def stroke_shapes(self, ctx, x, y):
|
||||
self.draw_shapes(ctx, x, y, False)
|
||||
|
||||
def draw(self, da, ctx):
|
||||
ctx.set_source_rgb(0, 0, 0)
|
||||
ctx.set_line_width(SIZE / 4)
|
||||
ctx.set_tolerance(0.1)
|
||||
ctx.set_line_join(cairo.LINE_JOIN_ROUND)
|
||||
ctx.set_dash([SIZE / 4.0, SIZE / 4.0], 0)
|
||||
self.stroke_shapes(ctx, 0, 0)
|
||||
ctx.set_dash([], 0)
|
||||
self.stroke_shapes(ctx, 0, 3 * SIZE)
|
||||
ctx.set_line_join(cairo.LINE_JOIN_BEVEL)
|
||||
self.stroke_shapes(ctx, 0, 6 * SIZE)
|
||||
ctx.set_line_join(cairo.LINE_JOIN_MITER)
|
||||
self.stroke_shapes(ctx, 0, 9 * SIZE)
|
||||
self.fill_shapes(ctx, 0, 12 * SIZE)
|
||||
ctx.set_line_join(cairo.LINE_JOIN_BEVEL)
|
||||
self.fill_shapes(ctx, 0, 15 * SIZE)
|
||||
ctx.set_source_rgb(1, 0, 0)
|
||||
self.stroke_shapes(ctx, 0, 15 * SIZE)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Drawing Areas")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
47
More_Widgets/GtkEntryCompletion.py
Normal file
47
More_Widgets/GtkEntryCompletion.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, GObject
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
widgets = ["GtkDialog", "GtkWindow", "GtkContainer", "GtkWidget"]
|
||||
self.set_border_width(10)
|
||||
label = Gtk.Label.new("Enter a widget in the following GtkEntry:")
|
||||
entry = Gtk.Entry.new()
|
||||
# Create a GtkListStore that will hold autocompletion possibilities.
|
||||
types = (GObject.TYPE_STRING,)
|
||||
store = Gtk.ListStore.new(types)
|
||||
for widget in widgets:
|
||||
iter = store.append()
|
||||
store.set(iter, 0, widget)
|
||||
completion = Gtk.EntryCompletion.new()
|
||||
entry.set_completion(completion)
|
||||
completion.set_model(store)
|
||||
completion.set_text_column(0)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_start(label, False, False, 0)
|
||||
vbox.pack_start(entry, False, False, 0)
|
||||
self.add(vbox)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Automatic Completion")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
141
More_Widgets/GtkPrintOperation.py
Normal file
141
More_Widgets/GtkPrintOperation.py
Normal file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import math
|
||||
from os.path import expanduser
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
gi.require_version('PangoCairo', '1.0')
|
||||
from gi.repository import Gtk, cairo, Pango, PangoCairo
|
||||
|
||||
class Widgets:
|
||||
|
||||
def __init__(self):
|
||||
self.window = None
|
||||
self.chooser = None
|
||||
self.data = None
|
||||
self.settings = Gtk.PrintSettings.new()
|
||||
|
||||
class PrintData:
|
||||
|
||||
def __init__(self):
|
||||
self.filename = None
|
||||
self.fontsize = None
|
||||
self.lines_per_page = None
|
||||
self.lines = None
|
||||
self.total_lines = None
|
||||
self.total_pages = None
|
||||
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.HEADER_HEIGHT = 20.0
|
||||
self.HEADER_GAP = 8.5
|
||||
w = Widgets()
|
||||
w.window = self
|
||||
self.set_border_width(10)
|
||||
w.chooser = Gtk.FileChooserButton.new ("Select a File",
|
||||
Gtk.FileChooserAction.OPEN)
|
||||
w.chooser.set_current_folder(expanduser("~"))
|
||||
print = Gtk.Button.new_with_label("Print")
|
||||
print.connect("clicked", self.print_file, w)
|
||||
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5)
|
||||
hbox.pack_start(w.chooser, False, False, 0)
|
||||
hbox.pack_start(print, False, False, 0)
|
||||
self.add(hbox)
|
||||
|
||||
def print_file(self, button, w):
|
||||
filename = w.chooser.get_filename()
|
||||
if filename == None:
|
||||
return
|
||||
operation = Gtk.PrintOperation.new()
|
||||
if w.settings != None:
|
||||
operation.set_print_settings(w.settings)
|
||||
w.data = PrintData()
|
||||
w.data.filename = filename
|
||||
w.data.font_size = 10.0
|
||||
operation.connect("begin_print", self.begin_print, w)
|
||||
operation.connect("draw_page", self.draw_page, w)
|
||||
operation.connect("end_print", self.end_print, w)
|
||||
res = operation.run(Gtk.PrintOperationAction.PRINT_DIALOG,
|
||||
w.window)
|
||||
if res == Gtk.PrintOperationResult.APPLY:
|
||||
if w.settings != None:
|
||||
w.settings = None
|
||||
settings = operation.get_print_settings()
|
||||
elif res == Gtk.PrintOperationResult.ERROR:
|
||||
dialog = Gtk.MessageDialog.new(w.window,
|
||||
Gtk.DialogFlags.DESTROY_WITH_PARENT,
|
||||
Gtk.MessageType.ERROR,
|
||||
Gtk.ButtonsType.S_CLOSE,
|
||||
"Print operation error.")
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
def begin_print(self, operation, context, w):
|
||||
w.data.lines = []
|
||||
f = open(w.data.filename)
|
||||
for line in f:
|
||||
w.data.lines.append(line)
|
||||
f.close()
|
||||
w.data.total_lines = len(w.data.lines)
|
||||
height = context.get_height() - self.HEADER_HEIGHT - self.HEADER_GAP
|
||||
w.data.lines_per_page = math.floor(height / (w.data.font_size + 3))
|
||||
w.data.total_pages = (w.data.total_lines - 1) / w.data.lines_per_page + 1
|
||||
operation.set_n_pages(w.data.total_pages)
|
||||
|
||||
def draw_page(self, operation, context, page_nr, w):
|
||||
cr = context.get_cairo_context()
|
||||
width = context.get_width()
|
||||
layout = context.create_pango_layout()
|
||||
desc = Pango.font_description_from_string("Monospace")
|
||||
desc.set_size(w.data.font_size * Pango.SCALE)
|
||||
layout.set_font_description(desc)
|
||||
layout.set_text(w.data.filename, -1)
|
||||
layout.set_width(-1)
|
||||
layout.set_alignment(Pango.Alignment.LEFT)
|
||||
(width, height) = layout.get_size()
|
||||
text_height = height / Pango.SCALE
|
||||
cr.move_to(0, (self.HEADER_HEIGHT - text_height) / 2)
|
||||
PangoCairo.show_layout(cr, layout)
|
||||
page_str = "%d of %d" % (page_nr + 1, w.data.total_pages)
|
||||
layout.set_text(page_str, -1)
|
||||
(width, height) = layout.get_size()
|
||||
layout.set_alignment(Pango.Alignment.RIGHT)
|
||||
cr.move_to(width - (width / Pango.SCALE),
|
||||
(self.HEADER_HEIGHT - text_height) / 2)
|
||||
PangoCairo.show_layout(cr, layout)
|
||||
cr.move_to(0, self.HEADER_HEIGHT + self.HEADER_GAP)
|
||||
line = page_nr * w.data.lines_per_page
|
||||
#for (i = 0; i < w.data.lines_per_page && line < w.data.total_lines; i++)
|
||||
i = 0
|
||||
while i < w.data.lines_per_page and line < w.data.total_lines:
|
||||
layout.set_text(w.data.lines[line], -1)
|
||||
PangoCairo.show_layout(cr, layout)
|
||||
cr.rel_move_to(0, w.data.font_size + 3)
|
||||
line += 1
|
||||
i += 1
|
||||
|
||||
def end_print(self, operation, context, w):
|
||||
w.data.lines = None
|
||||
w.data = None
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Calendar")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
170
More_Widgets/RecentFileChooserDialog.py
Normal file
170
More_Widgets/RecentFileChooserDialog.py
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import urllib
|
||||
from urllib.request import pathname2url
|
||||
import os
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Pango
|
||||
|
||||
class Widgets():
|
||||
|
||||
def __init__(self):
|
||||
self.window = None
|
||||
self.textview = None
|
||||
self.recent = None
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
w = Widgets()
|
||||
w.window = self
|
||||
self.set_border_width(5)
|
||||
self.set_size_request(600, 400)
|
||||
w.textview = Gtk.TextView.new()
|
||||
fd = Pango.font_description_from_string("Monospace 10")
|
||||
self.modify_font(fd)
|
||||
swin = Gtk.ScrolledWindow.new(None, None)
|
||||
openbutton = Gtk.Button.new_with_label("open")
|
||||
save = Gtk.Button.new_with_label("Save")
|
||||
icon_theme = Gtk.IconTheme.get_default()
|
||||
icon = icon_theme.load_icon("document-open", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
image = Gtk.Image.new_from_pixbuf(icon)
|
||||
w.recent = Gtk.MenuToolButton.new(image, "Recent Files")
|
||||
manager = Gtk.RecentManager.get_default()
|
||||
menu = Gtk.RecentChooserMenu.new_for_manager(manager)
|
||||
w.recent.set_menu(menu)
|
||||
menu.set_show_not_found(False)
|
||||
menu.set_local_only(True)
|
||||
menu.set_limit(10)
|
||||
menu.set_sort_type(Gtk.RecentSortType.MRU)
|
||||
menu.connect("selection-done", self.menu_activated, w)
|
||||
openbutton.connect("clicked", self.open_file, w)
|
||||
save.connect("clicked", self.save_file, w)
|
||||
w.recent.connect("clicked", self.open_recent_file, w)
|
||||
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5)
|
||||
hbox.pack_start(openbutton, False, False, 0)
|
||||
hbox.pack_start(save, False, False, 0)
|
||||
hbox.pack_start(w.recent, False, False, 0)
|
||||
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5)
|
||||
swin.add(w.textview)
|
||||
vbox.pack_start(hbox, False, False, 0)
|
||||
vbox.pack_start(swin, True, True, 0)
|
||||
w.window.add(vbox)
|
||||
|
||||
def save_file(self, save, w):
|
||||
filename = w.window.get_title()
|
||||
buffer = w.textview.get_buffer()
|
||||
(start, end) = buffer.get_bounds()
|
||||
content = buffer.get_text(start, end, False)
|
||||
f = open(filename, 'w')
|
||||
f.write(content)
|
||||
f.close()
|
||||
|
||||
def menu_activated(self, menu, w):
|
||||
filename = menu.get_current_uri()
|
||||
if filename != None:
|
||||
fn = os.path.basename(filename)
|
||||
f = open(fn, 'r')
|
||||
contents = f.read()
|
||||
f.close()
|
||||
w.window.set_title(fn)
|
||||
buffer = w.textview.get_buffer()
|
||||
buffer.set_text(content, -1)
|
||||
else:
|
||||
print("The file '%s' could not be read!" % filename)
|
||||
|
||||
def open_file(self, openbutton, w):
|
||||
dialog = Gtk.FileChooserDialog(title="Open File", parent=w.window,
|
||||
action=Gtk.FileChooserAction.OPEN,
|
||||
buttons=("Cancel",
|
||||
Gtk.ResponseType.CANCEL,
|
||||
"Open",
|
||||
Gtk.ResponseType.OK))
|
||||
if dialog.run() == Gtk.ResponseType.OK:
|
||||
filename = dialog.get_filename()
|
||||
content = ""
|
||||
f = open(filename, 'r')
|
||||
content = f.read()
|
||||
f.close()
|
||||
if len(content) > 0:
|
||||
# Create a new recently used resource.
|
||||
data = Gtk.RecentData()
|
||||
data.display_name = None
|
||||
data.description = None
|
||||
data.mime_type = "text/plain"
|
||||
data.app_name = os.path.basename(__file__)
|
||||
data.app_exec = " " + data.app_name + "%u"
|
||||
#data.groups = ["testapp", None]
|
||||
data.is_private = False
|
||||
url = pathname2url(filename)
|
||||
# Add the recently used resource to the default recent manager.
|
||||
manager = Gtk.RecentManager.get_default()
|
||||
result = manager.add_full(url, data)
|
||||
# Load the file and set the filename as the title of the window.
|
||||
w.window.set_title(filename)
|
||||
buffer = w.textview.get_buffer()
|
||||
buffer.set_text(content, -1)
|
||||
dialog.destroy()
|
||||
|
||||
def open_recent_file(self, recent, w):
|
||||
manager = Gtk.RecentManager.get_default()
|
||||
dialog = Gtk.RecentChooserDialog(title="Open Recent File",
|
||||
parent=w.window,
|
||||
recent_manager=manager,
|
||||
buttons=("Cancel",
|
||||
Gtk.ResponseType.CANCEL,
|
||||
"Open",
|
||||
Gtk.ResponseType.OK))
|
||||
# Add a filter that will display all of the files in the dialog.
|
||||
filter = Gtk.RecentFilter.new()
|
||||
filter.set_name("All Files")
|
||||
filter.add_pattern("*")
|
||||
dialog.add_filter(filter)
|
||||
# Add another filter that will only display plain text files.
|
||||
filter = Gtk.RecentFilter.new()
|
||||
filter.set_name("Plain Text")
|
||||
filter.add_mime_type("text/plain")
|
||||
dialog.add_filter(filter)
|
||||
dialog.set_show_not_found(False)
|
||||
dialog.set_local_only(True)
|
||||
dialog.set_limit(10)
|
||||
dialog.set_sort_type(Gtk.RecentSortType.MRU)
|
||||
if dialog.run() == Gtk.ResponseType.OK:
|
||||
filename = dialog.get_current_uri()
|
||||
if filename != None:
|
||||
# Remove the "file://" prefix from the beginning of the
|
||||
# URI if it exists.
|
||||
content = ""
|
||||
fn = os.path.basename(filename)
|
||||
f = open(fn, 'r')
|
||||
contents = f.read()
|
||||
f.close()
|
||||
if len(content) > 0:
|
||||
w.window.set_title(fn)
|
||||
buffer = w.textview.get_buffer()
|
||||
buffer.set_text(content, -1)
|
||||
else:
|
||||
print("The file '%s' could not be read!" % filename)
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Recent Files")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
16
README.md
Normal file
16
README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Apress Source Code
|
||||
|
||||
This repository accompanies [*Foundations of PyGTK Development*](https://www.apress.com/9781484241783) by W. David Ashley and Andrew Krause (Apress, 2019).
|
||||
|
||||
[comment]: #cover
|
||||

|
||||
|
||||
Download the files as a zip using the green button, or clone the repository to your machine using Git.
|
||||
|
||||
## Releases
|
||||
|
||||
Release v1.0 corresponds to the code in the published book, without corrections or updates.
|
||||
|
||||
## Contributions
|
||||
|
||||
See the file Contributing.md for more information on how you can contribute to this repository.
|
41
Simple_Applications/Exercise_1.py
Normal file
41
Simple_Applications/Exercise_1.py
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
label = Gtk.Label.new("Bunny")
|
||||
label.set_selectable(True)
|
||||
self.add(label)
|
||||
self.set_size_request(300, 100)
|
||||
self.set_resizable(False)
|
||||
self.connect("key-press-event", self.on_window_keypress, label)
|
||||
|
||||
def on_window_keypress(self, window, event, label):
|
||||
tmp = label.get_text()
|
||||
label.set_text(self.get_title())
|
||||
self.set_title(tmp)
|
||||
return False
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Bugs")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
27
Simple_Applications/HelloWorld.py
Normal file
27
Simple_Applications/HelloWorld.py
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Main Window")
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
38
Simple_Applications/HelloWorld_With_Button.py
Normal file
38
Simple_Applications/HelloWorld_With_Button.py
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(25)
|
||||
button = Gtk.Button.new_with_mnemonic("_Close")
|
||||
button.connect("clicked", self.on_button_clicked)
|
||||
button.set_relief(Gtk.ReliefStyle.NORMAL)
|
||||
self.add(button)
|
||||
self.set_size_request(200, 100)
|
||||
|
||||
def on_button_clicked(self, button):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Hello World!")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
33
Simple_Applications/HelloWorld_With_Label.py
Normal file
33
Simple_Applications/HelloWorld_With_Label.py
Normal file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
label = Gtk.Label.new("Hello World!")
|
||||
label.set_selectable(True)
|
||||
self.add(label)
|
||||
self.set_size_request(200, 100)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Hello World!")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
165
Text_View_Widget/Exercise_1.py
Normal file
165
Text_View_Widget/Exercise_1.py
Normal file
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(300, -1)
|
||||
|
||||
textview = Gtk.TextView.new()
|
||||
search = Gtk.Entry.new()
|
||||
search.set_text("Search for ...")
|
||||
|
||||
new = Gtk.Button.new_with_label("New")
|
||||
openb = Gtk.Button.new_with_label("Open")
|
||||
save = Gtk.Button.new_with_label("Save")
|
||||
cut = Gtk.Button.new_with_label("Cut")
|
||||
copy = Gtk.Button.new_with_label("Copy")
|
||||
paste = Gtk.Button.new_with_label("Paste")
|
||||
find = Gtk.Button.new_with_label("Find")
|
||||
|
||||
new.connect("clicked", self.on_new_clicked, textview)
|
||||
openb.connect("clicked", self.on_open_clicked, textview)
|
||||
save.connect("clicked", self.on_save_clicked, textview)
|
||||
cut.connect("clicked", self.on_cut_clicked, textview)
|
||||
copy.connect("clicked", self.on_copy_clicked, textview)
|
||||
paste.connect("clicked", self.on_paste_clicked, textview)
|
||||
find.connect("clicked", self.on_find_clicked, textview, search)
|
||||
|
||||
scrolled_win = Gtk.ScrolledWindow.new()
|
||||
scrolled_win.add(textview)
|
||||
|
||||
vbox1 = Gtk.Box.new (Gtk.Orientation.VERTICAL, 5)
|
||||
vbox1.pack_start(new, False, False, 0)
|
||||
vbox1.pack_start(openb, False, False, 0)
|
||||
vbox1.pack_start(save, False, False, 0)
|
||||
vbox1.pack_start(cut, False, False, 0)
|
||||
vbox1.pack_start(copy, False, False, 0)
|
||||
vbox1.pack_start(paste, False, False, 0)
|
||||
|
||||
searchbar = Gtk.Box.new (Gtk.Orientation.HORIZONTAL, 5)
|
||||
searchbar.pack_start(search, False, False, 0)
|
||||
searchbar.pack_start(find, False, False, 0)
|
||||
|
||||
hbox1 = Gtk.Box.new (Gtk.Orientation.HORIZONTAL, 5)
|
||||
hbox1.pack_start(scrolled_win, True, True, 0)
|
||||
hbox1.pack_start(vbox1, False, False, 0)
|
||||
|
||||
vbox2 = Gtk.Box.new (Gtk.Orientation.VERTICAL, 5)
|
||||
vbox2.pack_start(hbox1, True, True, 0)
|
||||
vbox2.pack_start(searchbar, False, False, 0)
|
||||
|
||||
self.add(vbox2)
|
||||
self.show_all()
|
||||
|
||||
def on_new_clicked(self, button, textview):
|
||||
dialog = Gtk.MessageDialog(title="Question", parent=self,
|
||||
flags=Gtk.DialogFlags.MODAL)
|
||||
dialog.set_border_width(10)
|
||||
dialog.add_button("Yes", Gtk.ResponseType.YES)
|
||||
dialog.add_button("No", Gtk.ResponseType.NO)
|
||||
dialog.props.text = "All changes will be lost.\nDo you want to continue?"
|
||||
dialog.show_all()
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.YES:
|
||||
buffer = textview.get_buffer()
|
||||
buffer.set_text("")
|
||||
dialog.destroy()
|
||||
|
||||
def on_open_clicked(self, button, textview):
|
||||
dialog = Gtk.FileChooserDialog(title="Choose a file ..",
|
||||
parent=self,
|
||||
flags=Gtk.FileChooserAction.OPEN,
|
||||
buttons=("Open", Gtk.ResponseType.APPLY,
|
||||
"Cancel", Gtk.ResponseType.CANCEL))
|
||||
dialog.show_all()
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.APPLY:
|
||||
buffer = textview.get_buffer()
|
||||
file = dialog.get_filename()
|
||||
f = open(file, 'r')
|
||||
content = f.read()
|
||||
f.close()
|
||||
buffer.set_text(content)
|
||||
dialog.destroy()
|
||||
|
||||
def on_save_clicked(self, button, textview):
|
||||
dialog = Gtk.FileChooserDialog(title="Save the file ..",
|
||||
parent=self,
|
||||
flags=Gtk.FileChooserAction.SAVE,
|
||||
buttons=("Save", Gtk.ResponseType.APPLY,
|
||||
"Cancel", Gtk.ResponseType.CANCEL))
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.APPLY:
|
||||
file = dialog.get_filename()
|
||||
buffer = textview.get_buffer()
|
||||
(start, end) = buffer.get_bounds()
|
||||
content = buffer.get_text(start, end, True)
|
||||
f = open(file, 'w')
|
||||
f.write(content)
|
||||
f.close()
|
||||
dialog.destroy()
|
||||
|
||||
def on_cut_clicked(self, button, textview):
|
||||
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
||||
buffer = textview.get_buffer()
|
||||
buffer.cut_clipboard(clipboard, True)
|
||||
|
||||
def on_copy_clicked(self, button, textview):
|
||||
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
||||
buffer = textview.get_buffer()
|
||||
buffer.copy_clipboard(clipboard)
|
||||
|
||||
def on_paste_clicked(self, button, textview):
|
||||
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
||||
buffer = textview.get_buffer()
|
||||
buffer.paste_clipboard(clipboard, None, True)
|
||||
|
||||
def on_find_clicked(self, button, textview, search):
|
||||
find = search.get_text()
|
||||
buffer = textview.get_buffer()
|
||||
cursorpos = buffer.props.cursor_position
|
||||
start = buffer.get_iter_at_offset(cursorpos)
|
||||
end = buffer.get_iter_at_offset(-1)
|
||||
if start.compare(end) != 0:
|
||||
start.forward_char()
|
||||
success = start.forward_search(find, 0, None)
|
||||
if success != None and len(success) != 0:
|
||||
(start, end) = success
|
||||
mark = buffer.create_mark(None, start, False)
|
||||
textview.scroll_mark_onscreen(mark)
|
||||
buffer.delete_mark(mark)
|
||||
buffer.select_range(start, end)
|
||||
else:
|
||||
dialog = Gtk.MessageDialog(title="Information", parent=self,
|
||||
flags=Gtk.DialogFlags.MODAL)
|
||||
dialog.set_border_width(10)
|
||||
dialog.add_button("Ok", Gtk.ResponseType.OK)
|
||||
dialog.props.text = "The text was not found!"
|
||||
dialog.show_all()
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Exercise 1")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
49
Text_View_Widget/GtkTextBuffer_Child.py
Normal file
49
Text_View_Widget/GtkTextBuffer_Child.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(25)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, 100)
|
||||
textview = Gtk.TextView.new()
|
||||
buffer = textview.get_buffer()
|
||||
text = "\n Click to exit!"
|
||||
buffer.set_text(text, len(text))
|
||||
iter = buffer.get_iter_at_offset(8)
|
||||
anchor = buffer.create_child_anchor(iter)
|
||||
button = Gtk.Button.new_with_label("the button")
|
||||
button.connect("clicked", self.on_button_clicked)
|
||||
button.set_relief(Gtk.ReliefStyle.NORMAL)
|
||||
textview.add_child_at_anchor(button, anchor)
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.add(textview)
|
||||
scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC,
|
||||
Gtk.PolicyType.ALWAYS)
|
||||
self.add(scrolled_win)
|
||||
|
||||
def on_button_clicked(self, button):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Child Widgets")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
101
Text_View_Widget/GtkTextBuffer_Formatted.py
Normal file
101
Text_View_Widget/GtkTextBuffer_Formatted.py
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Pango
|
||||
|
||||
text_to_scales = [("Quarter Sized", 0.25),
|
||||
("Double Extra Small", 0.5787037037037),
|
||||
("Extra Small", 0.6444444444444),
|
||||
("Small", 0.8333333333333),
|
||||
("Medium", 1.0), ("Large", 1.2),
|
||||
("Extra Large", 1.4399999999999),
|
||||
("Double Extra Large", 1.728),
|
||||
("Double Sized", 2.0)]
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(500, -1)
|
||||
textview = Gtk.TextView.new()
|
||||
buffer = textview.get_buffer()
|
||||
buffer.create_tag("bold", weight=Pango.Weight.BOLD)
|
||||
buffer.create_tag("italic", style=Pango.Style.ITALIC)
|
||||
buffer.create_tag("strike", strikethrough=True)
|
||||
buffer.create_tag("underline", underline=Pango.Underline.SINGLE)
|
||||
bold = Gtk.Button.new_with_label("Bold")
|
||||
italic = Gtk.Button.new_with_label("Italic")
|
||||
strike = Gtk.Button.new_with_label("Strike")
|
||||
underline = Gtk.Button.new_with_label("Underline")
|
||||
clear = Gtk.Button.new_with_label("Clear")
|
||||
scale_button = Gtk.ComboBoxText.new()
|
||||
i = 0
|
||||
while i < len(text_to_scales):
|
||||
(name, scale) = text_to_scales[i]
|
||||
scale_button.append_text(name)
|
||||
buffer.create_tag(tag_name=name, scale=scale)
|
||||
i += 1
|
||||
bold.__setattr__("tag", "bold")
|
||||
italic.__setattr__("tag", "italic")
|
||||
strike.__setattr__("tag", "strike")
|
||||
underline.__setattr__("tag", "underline")
|
||||
bold.connect("clicked", self.on_format, textview)
|
||||
italic.connect("clicked", self.on_format, textview)
|
||||
strike.connect("clicked", self.on_format, textview)
|
||||
underline.connect("clicked", self.on_format, textview)
|
||||
clear.connect("clicked", self.on_clear_clicked, textview)
|
||||
scale_button.connect("changed", self.on_scale_changed, textview)
|
||||
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5)
|
||||
vbox.pack_start(bold, False, False, 0)
|
||||
vbox.pack_start(italic, False, False, 0)
|
||||
vbox.pack_start(strike, False, False, 0)
|
||||
vbox.pack_start(underline, False, False, 0)
|
||||
vbox.pack_start(scale_button, False, False, 0)
|
||||
vbox.pack_start(clear, False, False, 0)
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.add(textview)
|
||||
scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC,
|
||||
Gtk.PolicyType.ALWAYS)
|
||||
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5)
|
||||
hbox.pack_start(scrolled_win, True, True, 0)
|
||||
hbox.pack_start(vbox, False, True, 0)
|
||||
self.add(hbox)
|
||||
|
||||
def on_format(self, button, textview):
|
||||
tagname = button.tag
|
||||
buffer = textview.get_buffer()
|
||||
(start, end) = buffer.get_selection_bounds()
|
||||
buffer.apply_tag_by_name(tagname, start, end)
|
||||
|
||||
def on_scale_changed(self, button, textview):
|
||||
if button.get_active() == -1:
|
||||
return
|
||||
text = button.get_active_text()
|
||||
button.__setattr__("tag", text)
|
||||
self.on_format(button, textview)
|
||||
button.set_active(-1)
|
||||
|
||||
def on_clear_clicked(self, button, textview):
|
||||
buffer = textview.get_buffer()
|
||||
(start, end) = buffer.get_selection_bounds()
|
||||
buffer.remove_all_tags(start, end)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Text Tags")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
46
Text_View_Widget/GtkTextBuffer_Images.py
Normal file
46
Text_View_Widget/GtkTextBuffer_Images.py
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(200, 150)
|
||||
textview = Gtk.TextView.new()
|
||||
buffer = textview.get_buffer()
|
||||
text = " Undo\n Redo"
|
||||
buffer.set_text(text, len(text))
|
||||
icon_theme = Gtk.IconTheme.get_default()
|
||||
undo = icon_theme.load_icon("edit-undo", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
line = buffer.get_iter_at_line (0)
|
||||
buffer.insert_pixbuf(line, undo)
|
||||
redo = icon_theme.load_icon("edit-redo", -1,
|
||||
Gtk.IconLookupFlags.FORCE_SIZE)
|
||||
line = buffer.get_iter_at_line (1)
|
||||
buffer.insert_pixbuf(line, redo)
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.add(textview)
|
||||
self.add (scrolled_win)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Pixbufs")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
70
Text_View_Widget/GtkTextBuffer_Search.py
Normal file
70
Text_View_Widget/GtkTextBuffer_Search.py
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
textview = Gtk.TextView.new()
|
||||
entry = Gtk.Entry.new()
|
||||
entry.set_text("Search for ...")
|
||||
find = Gtk.Button.new_with_label("Find")
|
||||
find.connect("clicked", self.on_find_clicked, (textview, entry))
|
||||
scrolled_win = Gtk.ScrolledWindow.new (None, None)
|
||||
scrolled_win.set_size_request(250, 200)
|
||||
scrolled_win.add(textview)
|
||||
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5)
|
||||
hbox.pack_start(entry, True, True, 0)
|
||||
hbox.pack_start(find, True, True, 0)
|
||||
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5)
|
||||
vbox.pack_start(scrolled_win, True, True, 0)
|
||||
vbox.pack_start(hbox, True, True, 0)
|
||||
self.add(vbox)
|
||||
|
||||
def on_find_clicked(self, button, w):
|
||||
find = w[1].get_text()
|
||||
find_len = len(find)
|
||||
buffer = w[0].get_buffer()
|
||||
start = buffer.get_start_iter()
|
||||
end_itr = buffer.get_end_iter()
|
||||
i = 0
|
||||
while True:
|
||||
end = start.copy()
|
||||
end.forward_chars(find_len)
|
||||
text = buffer.get_text(start, end, False)
|
||||
if text == find:
|
||||
i += 1
|
||||
start.forward_chars(find_len)
|
||||
else:
|
||||
start.forward_char()
|
||||
if end.compare(end_itr) == 0:
|
||||
break
|
||||
output = "The string '"+find+"' was found " + str(i) + " times!"
|
||||
dialog = Gtk.MessageDialog(parent=self, flags=Gtk.DialogFlags.MODAL,
|
||||
message_type=Gtk.MessageType.INFO,
|
||||
text=output, title="Information",
|
||||
buttons=("OK", Gtk.ResponseType.OK))
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Searching Buffers")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
37
Text_View_Widget/GtkTextView.py
Normal file
37
Text_View_Widget/GtkTextView.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, 150)
|
||||
textview = Gtk.TextView.new()
|
||||
buffer = textview.get_buffer()
|
||||
text = "Your 1st GtkTextView widget!"
|
||||
buffer.set_text(text, len(text))
|
||||
scrolled_win = Gtk.ScrolledWindow.new (None, None)
|
||||
scrolled_win.add(textview)
|
||||
self.add(scrolled_win)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Text Views")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
51
Text_View_Widget/GtkTextViewProperties.py
Normal file
51
Text_View_Widget/GtkTextViewProperties.py
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Pango
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, 150)
|
||||
font = Pango.font_description_from_string("Monospace Bold 10")
|
||||
textview = Gtk.TextView.new()
|
||||
textview.modify_font(font)
|
||||
textview.set_wrap_mode(Gtk.WrapMode.WORD)
|
||||
textview.set_justification(Gtk.Justification.RIGHT)
|
||||
textview.set_editable(True)
|
||||
textview.set_cursor_visible(True)
|
||||
textview.set_pixels_above_lines(5)
|
||||
textview.set_pixels_below_lines(5)
|
||||
textview.set_pixels_inside_wrap(5)
|
||||
textview.set_left_margin(10)
|
||||
textview.set_right_margin(10)
|
||||
buffer = textview.get_buffer()
|
||||
text = "This is some text!\nChange me!\nPlease!"
|
||||
buffer.set_text(text, len(text))
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC,
|
||||
Gtk.PolicyType.ALWAYS)
|
||||
scrolled_win.add(textview)
|
||||
self.add(scrolled_win)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Text Views Properties")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
62
Text_View_Widget/GtkTextView_Menu.py
Normal file
62
Text_View_Widget/GtkTextView_Menu.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
textview = Gtk.TextView.new()
|
||||
cut = Gtk.Button.new_with_label("Cut")
|
||||
copy = Gtk.Button.new_with_label("Copy")
|
||||
paste = Gtk.Button.new_with_label("Paste")
|
||||
cut.connect("clicked", self.on_cut_clicked, textview)
|
||||
copy.connect("clicked", self.on_copy_clicked, textview)
|
||||
paste.connect("clicked", self.on_paste_clicked, textview)
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.set_size_request(300, 200)
|
||||
scrolled_win.add(textview)
|
||||
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5)
|
||||
hbox.pack_start(cut, True, True, 0)
|
||||
hbox.pack_start(copy, True, True, 0)
|
||||
hbox.pack_start(paste, True, True, 0)
|
||||
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5)
|
||||
vbox.pack_start(scrolled_win, True, True, 0)
|
||||
vbox.pack_start(hbox, True, True, 0)
|
||||
self.add(vbox)
|
||||
|
||||
def on_cut_clicked(self, button, textview):
|
||||
clipboard = Gtk.Clipboard.get(Gdk.Atom.intern("CLIPBOARD", False))
|
||||
buffer = textview.get_buffer()
|
||||
buffer.cut_clipboard(clipboard, True)
|
||||
|
||||
def on_copy_clicked(self, button, textview):
|
||||
clipboard = Gtk.Clipboard.get(Gdk.Atom.intern("CLIPBOARD", False))
|
||||
buffer = textview.get_buffer()
|
||||
buffer.copy_clipboard(clipboard)
|
||||
|
||||
def on_paste_clicked(self, button, textview):
|
||||
clipboard = Gtk.Clipboard.get(Gdk.Atom.intern("CLIPBOARD", False))
|
||||
buffer = textview.get_buffer()
|
||||
buffer.paste_clipboard (clipboard, None, True)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Cut, Copy & Paste")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
73
Text_View_Widget/ScrolledWindowAndViewport.py
Normal file
73
Text_View_Widget/ScrolledWindowAndViewport.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
grid1 = Gtk.Grid.new()
|
||||
grid2 = Gtk.Grid.new()
|
||||
grid1.set_column_homogeneous = True
|
||||
grid2.set_column_homogeneous = True
|
||||
grid1.set_row_homogeneous = True
|
||||
grid2.set_row_homogeneous = True
|
||||
grid1.set_column_spacing = 5
|
||||
grid2.set_column_spacing = 5
|
||||
grid1.set_row_spacing = 5
|
||||
grid2.set_row_spacing = 5
|
||||
i = 0
|
||||
while i < 10:
|
||||
j = 0
|
||||
while j < 10:
|
||||
button = Gtk.Button.new_with_label("Close")
|
||||
button.set_relief(Gtk.ReliefStyle.NONE)
|
||||
button.connect("clicked", self.on_button_clicked)
|
||||
grid1.attach(button, i, j, 1, 1)
|
||||
button = Gtk.Button.new_with_label("Close")
|
||||
button.set_relief(Gtk.ReliefStyle.NONE)
|
||||
button.connect("clicked", self.on_button_clicked)
|
||||
grid2.attach(button, i, j, 1, 1)
|
||||
j += 1
|
||||
i += 1
|
||||
swin = Gtk.ScrolledWindow.new(None, None)
|
||||
horizontal = swin.get_hadjustment()
|
||||
vertical = swin.get_vadjustment()
|
||||
viewport = Gtk.Viewport.new(horizontal, vertical)
|
||||
swin.set_border_width(5)
|
||||
swin.set_propagate_natural_width(True)
|
||||
swin.set_propagate_natural_height(True)
|
||||
viewport.set_border_width(5)
|
||||
swin.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
||||
swin.add_with_viewport(grid1)
|
||||
viewport.add(grid2)
|
||||
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5)
|
||||
vbox.set_homogeneous = True
|
||||
vbox.pack_start(viewport, True, True, 5)
|
||||
vbox.pack_start(swin, True, True, 5)
|
||||
self.add (vbox)
|
||||
self.show_all()
|
||||
|
||||
def on_button_clicked(self, button):
|
||||
self.destroy()
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Scrolled Windows & Viewports")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
60
Text_View_Widget/UsingGtkTextView.py
Normal file
60
Text_View_Widget/UsingGtkTextView.py
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(-1, -1)
|
||||
textview = Gtk.TextView.new()
|
||||
entry = Gtk.Entry.new()
|
||||
insert_button = Gtk.Button.new_with_label("Insert Text")
|
||||
retrieve = Gtk.Button.new_with_label("Get Text")
|
||||
insert_button.connect("clicked", self.on_insert_text, (entry, textview))
|
||||
retrieve.connect("clicked", self.on_retrieve_text, (entry, textview))
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.add(textview)
|
||||
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5)
|
||||
hbox.pack_start(entry, True, True, 0)
|
||||
hbox.pack_start(insert_button, True, True, 0)
|
||||
hbox.pack_start(retrieve, True, True, 0)
|
||||
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5)
|
||||
vbox.pack_start(scrolled_win, True, True, 0)
|
||||
vbox.pack_start(hbox, True, True, 0)
|
||||
self.add(vbox)
|
||||
self.show_all()
|
||||
|
||||
def on_insert_text(self, button, w):
|
||||
buffer = w[1].get_buffer()
|
||||
text = w[0].get_text()
|
||||
mark = buffer.get_insert()
|
||||
iter = buffer.get_iter_at_mark(mark)
|
||||
buffer.insert(iter, text, len(text))
|
||||
|
||||
def on_retrieve_text(self, button, w):
|
||||
buffer = w[1].get_buffer()
|
||||
(start, end) = buffer.get_selection_bounds()
|
||||
text = buffer.get_text(start, end, False)
|
||||
print(text)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Text Iterators")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
73
Tree_View_Widget/AccelCellRenderers.py
Normal file
73
Tree_View_Widget/AccelCellRenderers.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk, GObject
|
||||
|
||||
ACTION = 0
|
||||
MASK = 1
|
||||
VALUE = 2
|
||||
|
||||
list = [( "Cut", Gdk.ModifierType.CONTROL_MASK, Gdk.KEY_X ),
|
||||
( "Copy", Gdk.ModifierType.CONTROL_MASK, Gdk.KEY_C ),
|
||||
( "Paste", Gdk.ModifierType.CONTROL_MASK, Gdk.KEY_V ),
|
||||
( "New", Gdk.ModifierType.CONTROL_MASK, Gdk.KEY_N ),
|
||||
( "Open", Gdk.ModifierType.CONTROL_MASK, Gdk.KEY_O ),
|
||||
( "Print", Gdk.ModifierType.CONTROL_MASK, Gdk.KEY_P )]
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_size_request(250, 250)
|
||||
treeview = Gtk.TreeView.new()
|
||||
self.setup_tree_view(treeview)
|
||||
store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_INT,
|
||||
GObject.TYPE_UINT)
|
||||
for row in list:
|
||||
(action, mask, value) = row
|
||||
iter = store.append(None)
|
||||
store.set(iter, ACTION, action, MASK, mask, VALUE, value)
|
||||
treeview.set_model(store)
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC,
|
||||
Gtk.PolicyType.AUTOMATIC)
|
||||
scrolled_win.add(treeview)
|
||||
self.add(scrolled_win)
|
||||
|
||||
def setup_tree_view(self, treeview):
|
||||
renderer = Gtk.CellRendererAccel()
|
||||
column = Gtk.TreeViewColumn("Action", renderer, text=ACTION)
|
||||
treeview.append_column(column)
|
||||
renderer = Gtk.CellRendererAccel(accel_mode=Gtk.CellRendererAccelMode.GTK,
|
||||
editable=True)
|
||||
column = Gtk.TreeViewColumn("Key", renderer, accel_mods=MASK,
|
||||
accel_key=VALUE)
|
||||
treeview.append_column(column)
|
||||
renderer.connect("accel_edited", self.accel_edited, treeview)
|
||||
|
||||
def accel_edited(self, renderer, path, accel_key, mask,
|
||||
hardware_keycode, treeview):
|
||||
model = treeview.get_model()
|
||||
iter = model.get_iter_from_string(path)
|
||||
if iter:
|
||||
model.set(iter, MASK, mask, VALUE, accel_key)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self,
|
||||
title="Accelerator Keys")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
32
Tree_View_Widget/ComboBoxCellRenderers.py
Normal file
32
Tree_View_Widget/ComboBoxCellRenderers.py
Normal file
@@ -0,0 +1,32 @@
|
||||
def setup_tree_view(self, treeview):
|
||||
# Create a GtkListStore that will be used for the combo box renderer.
|
||||
model = Gtk.ListStore.new((GObject.TYPE_STRING,
|
||||
GObject.TYPE_STRING))
|
||||
iter = model.append()
|
||||
model.set(iter, 0, "None")
|
||||
iter = model.append()
|
||||
model.set(iter, 0, "One")
|
||||
iter = model.append()
|
||||
model.set(iter, 0, "Half a Dozen")
|
||||
iter = model.append()
|
||||
model.set(iter, 0, "Dozen")
|
||||
iter = model.append()
|
||||
model.set(iter, 0, "Two Dozen")
|
||||
# Create the GtkCellRendererCombo and add the tree model. Then, add the
|
||||
# renderer to a new column and add the column to the GtkTreeView.
|
||||
renderer = Gtk.CellRendererCombo(text_column=0, editable=True,
|
||||
has_entry=True, model=model)
|
||||
column = Gtk.TreeViewColumn("Count", renderer, text=QUANTITY)
|
||||
treeview.append_column(column)
|
||||
renderer.connect("edited", self.cell_edited, treeview)
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn("Product", renderer, text=PRODUCT)
|
||||
treeview.append_column(column)
|
||||
|
||||
def cell_edited(self, renderer, path, new_text, treeview):
|
||||
# Make sure the text is not empty. If not, apply it to the tree view cell.
|
||||
if new_text != "":
|
||||
model = treeview.get_model()
|
||||
iter = model.get_iter_from_string(path)
|
||||
if iter:
|
||||
model.set(iter, QUANTITY, new_text)
|
172
Tree_View_Widget/Edit_GroceryList.py
Normal file
172
Tree_View_Widget/Edit_GroceryList.py
Normal file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, GObject
|
||||
|
||||
BUY_IT = 0
|
||||
QUANTITY = 1
|
||||
PRODUCT = 2
|
||||
|
||||
PRODUCT_CATEGORY = 0
|
||||
PRODUCT_CHILD = 1
|
||||
|
||||
GroceryItem = (( PRODUCT_CATEGORY, True, 0, "Cleaning Supplies"),
|
||||
( PRODUCT_CHILD, True, 1, "Paper Towels" ),
|
||||
( PRODUCT_CHILD, True, 3, "Toilet Paper" ),
|
||||
( PRODUCT_CATEGORY, True, 0, "Food"),
|
||||
( PRODUCT_CHILD, True, 2, "Bread" ),
|
||||
( PRODUCT_CHILD, False, 1, "Butter" ),
|
||||
( PRODUCT_CHILD, True, 1, "Milk" ),
|
||||
( PRODUCT_CHILD, False, 3, "Chips" ),
|
||||
( PRODUCT_CHILD, True, 4, "Soda" ))
|
||||
|
||||
class AddDialog(Gtk.Dialog):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
parent = kwargs['parent']
|
||||
# set up buttons
|
||||
self.add_button("Add", Gtk.ResponseType.OK)
|
||||
self.add_button("Cancel", Gtk.ResponseType.CANCEL)
|
||||
# set up dialog widgets
|
||||
combobox = Gtk.ComboBoxText.new()
|
||||
entry = Gtk.Entry.new()
|
||||
spin = Gtk.SpinButton.new_with_range(0, 100, 1)
|
||||
check = Gtk.CheckButton.new_with_mnemonic("_Buy the Product")
|
||||
spin.set_digits(0)
|
||||
# Add all of the categories to the combo box.
|
||||
for row in GroceryItem:
|
||||
(ptype, buy, quant, prod) = row
|
||||
if ptype == PRODUCT_CATEGORY:
|
||||
combobox.append_text(prod)
|
||||
# create a grid
|
||||
grid = Gtk.Grid.new()
|
||||
grid.set_row_spacing (5)
|
||||
grid.set_column_spacing(5)
|
||||
# fill out the grid
|
||||
grid.attach(Gtk.Label.new("Category:"), 0, 0, 1, 1)
|
||||
grid.attach(Gtk.Label.new("Product:"), 0, 1, 1, 1)
|
||||
grid.attach(Gtk.Label.new("Quantity:"), 0, 2, 1, 1)
|
||||
grid.attach(combobox, 1, 0, 1, 1)
|
||||
grid.attach(entry, 1, 1, 1, 1)
|
||||
grid.attach(spin, 1, 2, 1, 1)
|
||||
grid.attach(check, 1, 3, 1, 1)
|
||||
self.get_content_area().pack_start(grid, True, True, 5)
|
||||
self.show_all()
|
||||
# run the dialog and check the results
|
||||
if self.run() != Gtk.ResponseType.OK:
|
||||
self.destroy()
|
||||
return
|
||||
quantity = spin.get_value()
|
||||
product = entry.get_text()
|
||||
category = combobox.get_active_text()
|
||||
buy = check.get_active()
|
||||
if product == "" or category == None:
|
||||
print("All of the fields were not correctly filled out!")
|
||||
return
|
||||
model = parent.get_treeview().get_model();
|
||||
iter = model.get_iter_from_string("0")
|
||||
# Retrieve an iterator pointing to the selected category.
|
||||
while iter:
|
||||
(name,) = model.get(iter, PRODUCT)
|
||||
if name.lower() == category.lower():
|
||||
break
|
||||
iter = model.iter_next(iter)
|
||||
# Convert the category iterator to a path so that it will not become invalid
|
||||
# and add the new product as a child of the category.
|
||||
path = model.get_path(iter)
|
||||
child = model.append(iter)
|
||||
model.set(child, BUY_IT, buy, QUANTITY, quantity, PRODUCT, product)
|
||||
# Add the quantity to the running total if it is to be purchased.
|
||||
if buy:
|
||||
iter = model.get_iter(path)
|
||||
(i,) = model.get(iter, QUANTITY)
|
||||
i += quantity
|
||||
model.set(iter, QUANTITY, i)
|
||||
self.destroy()
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(275, 270)
|
||||
self.treeview = Gtk.TreeView.new()
|
||||
self.setup_tree_view(self.treeview)
|
||||
store = Gtk.TreeStore.new((GObject.TYPE_BOOLEAN,
|
||||
GObject.TYPE_INT,
|
||||
GObject.TYPE_STRING))
|
||||
iter = None
|
||||
i = 0
|
||||
for row in GroceryItem:
|
||||
(ptype, buy, quant, prod) = row
|
||||
if ptype == PRODUCT_CATEGORY:
|
||||
j = i + 1
|
||||
(ptype1, buy1, quant1, prod1) = GroceryItem[j]
|
||||
while j < len(GroceryItem) and ptype1 == PRODUCT_CHILD:
|
||||
if buy1:
|
||||
quant += quant1
|
||||
j += 1;
|
||||
if j < len(GroceryItem):
|
||||
(ptype1, buy1, quant1, prod1) = GroceryItem[j]
|
||||
iter = store.append(None)
|
||||
store.set(iter, BUY_IT, buy, QUANTITY, quant, PRODUCT, prod)
|
||||
else:
|
||||
child = store.append(iter)
|
||||
store.set(child, BUY_IT, buy, QUANTITY, quant, PRODUCT, prod)
|
||||
i += 1
|
||||
self.treeview.set_model(store)
|
||||
self.treeview.expand_all()
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
||||
scrolled_win.add(self.treeview)
|
||||
button_add = Gtk.Button.new_with_label("Add")
|
||||
button_add.connect("clicked", self.on_add_button_clicked, self)
|
||||
button_remove = Gtk.Button.new_with_label("Remove")
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||
hbox.pack_end(button_remove, False, True, 5)
|
||||
hbox.pack_end(button_add, False, True, 5)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_end(hbox, False, True, 5)
|
||||
vbox.pack_end(scrolled_win, True, True, 5)
|
||||
self.add(vbox)
|
||||
|
||||
def setup_tree_view(self, treeview):
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn("Buy", renderer, text=BUY_IT)
|
||||
self.treeview.append_column(column)
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn("Count", renderer, text=QUANTITY)
|
||||
treeview.append_column(column)
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn("Product", renderer, text=PRODUCT)
|
||||
treeview.append_column(column)
|
||||
|
||||
|
||||
def on_add_button_clicked(self, button, parent):
|
||||
dialog = AddDialog(title="Add a Product", parent=parent,
|
||||
flags=Gtk.DialogFlags.MODAL)
|
||||
|
||||
def get_treeview(self):
|
||||
return self.treeview
|
||||
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Grocery List")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
179
Tree_View_Widget/Edit_GroceryList2.py
Normal file
179
Tree_View_Widget/Edit_GroceryList2.py
Normal file
@@ -0,0 +1,179 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, GObject
|
||||
|
||||
BUY_IT = 0
|
||||
QUANTITY = 1
|
||||
PRODUCT = 2
|
||||
|
||||
PRODUCT_CATEGORY = 0
|
||||
PRODUCT_CHILD = 1
|
||||
|
||||
GroceryItem = (( PRODUCT_CATEGORY, True, 0, "Cleaning Supplies"),
|
||||
( PRODUCT_CHILD, True, 1, "Paper Towels" ),
|
||||
( PRODUCT_CHILD, True, 3, "Toilet Paper" ),
|
||||
( PRODUCT_CATEGORY, True, 0, "Food"),
|
||||
( PRODUCT_CHILD, True, 2, "Bread" ),
|
||||
( PRODUCT_CHILD, False, 1, "Butter" ),
|
||||
( PRODUCT_CHILD, True, 1, "Milk" ),
|
||||
( PRODUCT_CHILD, False, 3, "Chips" ),
|
||||
( PRODUCT_CHILD, True, 4, "Soda" ))
|
||||
|
||||
class AddDialog(Gtk.Dialog):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
parent = kwargs['parent']
|
||||
# set up buttons
|
||||
self.add_button("Add", Gtk.ResponseType.OK)
|
||||
self.add_button("Cancel", Gtk.ResponseType.CANCEL)
|
||||
# set up dialog widgets
|
||||
combobox = Gtk.ComboBoxText.new()
|
||||
entry = Gtk.Entry.new()
|
||||
spin = Gtk.SpinButton.new_with_range(0, 100, 1)
|
||||
check = Gtk.CheckButton.new_with_mnemonic("_Buy the Product")
|
||||
spin.set_digits(0)
|
||||
# Add all of the categories to the combo box.
|
||||
for row in GroceryItem:
|
||||
(ptype, buy, quant, prod) = row
|
||||
if ptype == PRODUCT_CATEGORY:
|
||||
combobox.append_text(prod)
|
||||
# create a grid
|
||||
grid = Gtk.Grid.new()
|
||||
grid.set_row_spacing (5)
|
||||
grid.set_column_spacing(5)
|
||||
# fill out the grid
|
||||
grid.attach(Gtk.Label.new("Category:"), 0, 0, 1, 1)
|
||||
grid.attach(Gtk.Label.new("Product:"), 0, 1, 1, 1)
|
||||
grid.attach(Gtk.Label.new("Quantity:"), 0, 2, 1, 1)
|
||||
grid.attach(combobox, 1, 0, 1, 1)
|
||||
grid.attach(entry, 1, 1, 1, 1)
|
||||
grid.attach(spin, 1, 2, 1, 1)
|
||||
grid.attach(check, 1, 3, 1, 1)
|
||||
self.get_content_area().pack_start(grid, True, True, 5)
|
||||
self.show_all()
|
||||
# run the dialog and check the results
|
||||
if self.run() != Gtk.ResponseType.OK:
|
||||
self.destroy()
|
||||
return
|
||||
quantity = spin.get_value()
|
||||
product = entry.get_text()
|
||||
category = combobox.get_active_text()
|
||||
buy = check.get_active()
|
||||
if product == "" or category == None:
|
||||
print("All of the fields were not correctly filled out!")
|
||||
return
|
||||
model = parent.get_treeview().get_model();
|
||||
iter = model.get_iter_from_string("0")
|
||||
# Retrieve an iterator pointing to the selected category.
|
||||
while iter:
|
||||
(name,) = model.get(iter, PRODUCT)
|
||||
if name.lower() == category.lower():
|
||||
break
|
||||
iter = model.iter_next(iter)
|
||||
# Convert the category iterator to a path so that it will not become invalid
|
||||
# and add the new product as a child of the category.
|
||||
path = model.get_path(iter)
|
||||
child = model.append(iter)
|
||||
model.set(child, BUY_IT, buy, QUANTITY, quantity, PRODUCT, product)
|
||||
# Add the quantity to the running total if it is to be purchased.
|
||||
if buy:
|
||||
iter = model.get_iter(path)
|
||||
(i,) = model.get(iter, QUANTITY)
|
||||
i += quantity
|
||||
model.set(iter, QUANTITY, i)
|
||||
self.destroy()
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(275, 270)
|
||||
self.treeview = Gtk.TreeView.new()
|
||||
self.setup_tree_view(self.treeview)
|
||||
store = Gtk.TreeStore.new((GObject.TYPE_BOOLEAN,
|
||||
GObject.TYPE_INT,
|
||||
GObject.TYPE_STRING))
|
||||
iter = None
|
||||
i = 0
|
||||
for row in GroceryItem:
|
||||
(ptype, buy, quant, prod) = row
|
||||
if ptype == PRODUCT_CATEGORY:
|
||||
j = i + 1
|
||||
(ptype1, buy1, quant1, prod1) = GroceryItem[j]
|
||||
while j < len(GroceryItem) and ptype1 == PRODUCT_CHILD:
|
||||
if buy1:
|
||||
quant += quant1
|
||||
j += 1;
|
||||
if j < len(GroceryItem):
|
||||
(ptype1, buy1, quant1, prod1) = GroceryItem[j]
|
||||
iter = store.append(None)
|
||||
store.set(iter, BUY_IT, buy, QUANTITY, quant, PRODUCT, prod)
|
||||
else:
|
||||
child = store.append(iter)
|
||||
store.set(child, BUY_IT, buy, QUANTITY, quant, PRODUCT, prod)
|
||||
i += 1
|
||||
self.treeview.set_model(store)
|
||||
self.treeview.expand_all()
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
||||
scrolled_win.add(self.treeview)
|
||||
button_add = Gtk.Button.new_with_label("Add")
|
||||
button_add.connect("clicked", self.on_add_button_clicked, self)
|
||||
button_remove = Gtk.Button.new_with_label("Remove")
|
||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
|
||||
hbox.pack_end(button_remove, False, True, 5)
|
||||
hbox.pack_end(button_add, False, True, 5)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||
vbox.pack_end(hbox, False, True, 5)
|
||||
vbox.pack_end(scrolled_win, True, True, 5)
|
||||
self.add(vbox)
|
||||
|
||||
def setup_tree_view(self, treeview):
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn("Buy", renderer, text=BUY_IT)
|
||||
self.treeview.append_column(column)
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn("Count", renderer, text=QUANTITY)
|
||||
treeview.append_column(column)
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
renderer.set_property("editable", True)
|
||||
renderer.connect("edited", self.cell_edited, treeview)
|
||||
column = Gtk.TreeViewColumn("Product", renderer, text=PRODUCT)
|
||||
treeview.append_column(column)
|
||||
|
||||
|
||||
def on_add_button_clicked(self, button, parent):
|
||||
dialog = AddDialog(title="Add a Product", parent=parent,
|
||||
flags=Gtk.DialogFlags.MODAL)
|
||||
|
||||
def get_treeview(self):
|
||||
return self.treeview
|
||||
|
||||
def cell_edited(self, renderer, path, new_text, treeview):
|
||||
if len(new_text) > 0:
|
||||
model = treeview.get_model()
|
||||
iter = model.get_iter_from_string(path)
|
||||
if iter:
|
||||
model.set(iter, PRODUCT, new_text)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Grocery List")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
24
Tree_View_Widget/Editing_A_Cell.py
Normal file
24
Tree_View_Widget/Editing_A_Cell.py
Normal file
@@ -0,0 +1,24 @@
|
||||
def set_up_treeview(self, treeview):
|
||||
renderer = Gtk.CellRenderer.Text.new()
|
||||
column = Gtk.TreeViewColumn.new_with_attributes("Buy", renderer,
|
||||
"text", BUY_IT)
|
||||
treeview.append_column(column)
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn.new_with_attributes("Count", renderer,
|
||||
"text", QUANTITY)
|
||||
treeview.append_column(column)
|
||||
|
||||
# Set up the third column in the tree view to be editable.
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
renderer.set_property("editable", True)
|
||||
renderer.connect("edited", self.cell_edited, treeview)
|
||||
column = Gtk.TreeViewColumn.new_with_attributes("Product", renderer,
|
||||
"text", PRODUCT)
|
||||
treeview.append_column(column)
|
||||
|
||||
def cell_edited(self, renderer, path, new_text, treeview):
|
||||
if len(new_text) > 0:
|
||||
model = treeview.get_model()
|
||||
iter = model.get_iter_from_string(path)
|
||||
if iter:
|
||||
model.set(iter, PRODUCT, new_text)
|
119
Tree_View_Widget/Exercise_1.py
Normal file
119
Tree_View_Widget/Exercise_1.py
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys, os
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, GObject, GdkPixbuf
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.ICON = 0
|
||||
self.FILENAME = 1
|
||||
self.current_path = []
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, 500)
|
||||
|
||||
treeview = Gtk.TreeView.new()
|
||||
treeview.connect("row-activated", self.on_row_activated)
|
||||
|
||||
self.setup_tree_view(treeview)
|
||||
self.setup_tree_model(treeview)
|
||||
|
||||
scrolled_win = Gtk.ScrolledWindow.new()
|
||||
scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC,
|
||||
Gtk.PolicyType.AUTOMATIC)
|
||||
|
||||
scrolled_win.add(treeview)
|
||||
self.add(scrolled_win)
|
||||
|
||||
def setup_tree_view(self, treeview):
|
||||
column = Gtk.TreeViewColumn.new()
|
||||
column.set_title("File Browser")
|
||||
|
||||
renderer = Gtk.CellRendererPixbuf.new()
|
||||
column.pack_start(renderer, False)
|
||||
column.add_attribute(renderer, "pixbuf", self.ICON)
|
||||
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column.pack_start(renderer, True)
|
||||
column.add_attribute(renderer, "text", self.FILENAME)
|
||||
|
||||
treeview.append_column(column)
|
||||
|
||||
def setup_tree_model(self, treeview):
|
||||
store = Gtk.ListStore(GdkPixbuf.Pixbuf, GObject.TYPE_STRING)
|
||||
treeview.set_model(store)
|
||||
|
||||
self.populate_tree_model(treeview)
|
||||
|
||||
def populate_tree_model(self, treeview):
|
||||
store = treeview.get_model()
|
||||
store.clear()
|
||||
|
||||
# Build the tree path out of current_path.
|
||||
if self.current_path == []:
|
||||
location ="/"
|
||||
else:
|
||||
for temp in current_path:
|
||||
location = location + "/" + temp
|
||||
|
||||
iter = store.append()
|
||||
store.set(iter, self.ICON, directory, self.FILENAME, "..")
|
||||
|
||||
# Parse through the directory, adding all of its contents to the model.
|
||||
for file in os.listdir(location):
|
||||
temp = location + "/" + file
|
||||
|
||||
if os.path.isdir(file):
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file ("directory.png")
|
||||
else:
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file ("file.png")
|
||||
|
||||
iter = store.append()
|
||||
store.set(iter, self.ICON, pixbuf, self.FILENAME, file)
|
||||
|
||||
def on_row_activated(self, treeview, fpath, column):
|
||||
model = treeview.get_model()
|
||||
iter = model.get_iter(fpath)
|
||||
if iter:
|
||||
file = model.get(iter, self.FILENAME)
|
||||
|
||||
if file == "..":
|
||||
node = pop(current_path)
|
||||
self.populate_tree_model(treeview)
|
||||
else:
|
||||
if len(self.current_path) == 0:
|
||||
location = "/"
|
||||
else:
|
||||
if self.current_path == []:
|
||||
location ="/"
|
||||
else:
|
||||
for file in current_path:
|
||||
location = location + "/" + file
|
||||
|
||||
iter = store.append()
|
||||
store.set(iter, self.ICON, directory, self.FILENAME, "..")
|
||||
|
||||
if os.path.isdir(location):
|
||||
current_path = location
|
||||
self.populate_tree_model(treeview)
|
||||
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Exercise 1")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
66
Tree_View_Widget/GtkTreeView_GtkListStore.py
Normal file
66
Tree_View_Widget/GtkTreeView_GtkListStore.py
Normal file
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, GObject
|
||||
|
||||
BUY_IT = 0
|
||||
QUANTITY = 1
|
||||
PRODUCT = 2
|
||||
|
||||
GroceryItem = (( True, 1, "Paper Towels" ),
|
||||
( True, 2, "Bread" ),
|
||||
( False, 1, "Butter" ),
|
||||
( True, 1, "Milk" ),
|
||||
( False, 3, "Chips" ),
|
||||
( True, 4, "Soda" ))
|
||||
|
||||
class AppWindow(Gtk.ApplicationWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_border_width(10)
|
||||
self.set_size_request(250, 175)
|
||||
treeview = Gtk.TreeView.new()
|
||||
self.setup_tree_view(treeview)
|
||||
store = Gtk.ListStore.new((GObject.TYPE_BOOLEAN,
|
||||
GObject.TYPE_INT,
|
||||
GObject.TYPE_STRING))
|
||||
for row in GroceryItem:
|
||||
iter = store.append(None)
|
||||
store.set(iter, BUY_IT, row[BUY_IT], QUANTITY, row[QUANTITY], PRODUCT,
|
||||
row[PRODUCT])
|
||||
treeview.set_model(store)
|
||||
scrolled_win = Gtk.ScrolledWindow.new(None, None)
|
||||
scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
||||
scrolled_win.add(treeview)
|
||||
self.add(scrolled_win)
|
||||
|
||||
def setup_tree_view(self, treeview):
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn("Buy", renderer, text=BUY_IT)
|
||||
treeview.append_column(column)
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn("Count", renderer, text=QUANTITY)
|
||||
treeview.append_column(column)
|
||||
renderer = Gtk.CellRendererText.new()
|
||||
column = Gtk.TreeViewColumn("Product", renderer, text=PRODUCT)
|
||||
treeview.append_column(column)
|
||||
|
||||
class Application(Gtk.Application):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, application_id="org.example.myapp",
|
||||
**kwargs)
|
||||
self.window = None
|
||||
|
||||
def do_activate(self):
|
||||
if not self.window:
|
||||
self.window = AppWindow(application=self, title="Grocery List")
|
||||
self.window.show_all()
|
||||
self.window.present()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user