Initial commit

This commit is contained in:
Mark Powers
2019-01-02 14:53:58 -05:00
commit 5eabe8545e
113 changed files with 9313 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

BIN
9781484241783.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View 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

View 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">&lt;Primary&gt;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)

View 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)

View 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)

View 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)

View 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
View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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
View 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
View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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
View 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!

View 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)

View 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

View 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)

View 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)

View 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
View 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)

View 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)

View 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)

View 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)

View 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)

View 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
View 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)

View 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)

View 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
View 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)

View 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)

View 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>

View 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)

View 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>

View 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)

View 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>

View 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)

View 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
View 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
View 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
View 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)

View 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>

View 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
View 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
View 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
View 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
View 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 users 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.

View 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)

View 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>

View 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)

View 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>

View 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)

View 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)

View 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>

View 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>

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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
View 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)

View 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)

View 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)

View 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
View 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
![Cover image](9781484241783.jpg)
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.

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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