Files
GTK4PythonTutorial/part2.py
2022-05-05 22:32:33 +12:00

270 lines
8.5 KiB
Python

import sys
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gio, Gdk, Graphene, GLib
class Custom(Gtk.Widget):
def __init__(self):
super().__init__()
self.set_size_request(30, 30)
def do_snapshot(self, s):
#s.save()
print("sn")
red = Gdk.RGBA()
# red.red = 1.
# red.green = 0.
# red.blue = 0.
# red.alpha = 1.
r = Graphene.Rect()
r.init(0, 0, 70, 70)
print(r)
print(r.get_height())
red.red = 1
red.alpha = 1
print(red.to_string())
s.append_color(red, r)
#s.restore()
def do_measure(self, orientation, for_size):
print("m")
return 50, 50, -1, -1
pass
class MainWindow(Gtk.ApplicationWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_default_size(600, 250)
self.set_title("MyApp")
# Main layout containers
self.box1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.box2 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.box3 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.box2.set_spacing(10)
self.box2.set_margin_top(10)
self.box2.set_margin_bottom(10)
self.box2.set_margin_start(10)
self.box2.set_margin_end(10)
self.set_child(self.box1) # Horizontal box to window
self.box1.append(self.box2) # Put vert box in that box
self.box1.append(self.box3) # And another one, empty for now
# Add a button
self.button = Gtk.Button(label="Hello")
self.button.connect('clicked', self.hello)
self.box2.append(self.button) # But button in the first of the two vertical boxes
# Add a check button
self.check = Gtk.CheckButton(label="And goodbye?")
self.box2.append(self.check)
# Add a box containing a switch and label
self.switch_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.switch_box.set_spacing(5)
self.switch = Gtk.Switch()
self.switch.set_active(True) # Let's default it to on
self.switch.connect("state-set", self.switch_switched) # Lets trigger a function on state change
self.label = Gtk.Label(label="A switch")
self.switch_box.append(self.switch)
self.switch_box.append(self.label)
self.box2.append(self.switch_box)
self.slider = Gtk.Scale()
self.slider.set_digits(0) # Number of decimal places to use
self.slider.set_range(0, 10)
self.slider.set_draw_value(True) # Show a label with current value
self.slider.set_value(5) # Sets the current value/position
self.slider.connect('value-changed', self.slider_changed)
self.box2.append(self.slider)
self.header = Gtk.HeaderBar()
self.set_titlebar(self.header)
self.open_button = Gtk.Button(label="Open")
self.header.pack_start(self.open_button)
self.open_button.set_icon_name("document-open-symbolic")
self.open_dialog = Gtk.FileChooserNative.new(title="Choose a file",
parent=self, action=Gtk.FileChooserAction.OPEN)
self.open_dialog.connect("response", self.open_response)
self.open_button.connect("clicked", self.show_open_dialog)
f = Gtk.FileFilter()
f.set_name("Image files")
f.add_mime_type("image/jpeg")
f.add_mime_type("image/png")
self.open_dialog.add_filter(f)
# Create a new "Action"
action = Gio.SimpleAction.new("something", None)
action.connect("activate", self.print_something)
self.add_action(action) # Here the action is being added to the window, but you could add it to the
# application or an "ActionGroup"
# Create a new menu, containing that action
menu = Gio.Menu.new()
menu.append("Do Something", "win.something") # Or you would do app.grape if you had attached the
# action to the application
# Create a popover
self.popover = Gtk.PopoverMenu() # Create a new popover menu
self.popover.set_menu_model(menu)
# Create a menu button
self.hamburger = Gtk.MenuButton()
self.hamburger.set_popover(self.popover)
self.hamburger.set_icon_name("open-menu-symbolic") # Give it a nice icon
# Add menu button to the header bar
self.header.pack_start(self.hamburger)
# set app name
GLib.set_application_name("My App")
# Add an about dialog
action = Gio.SimpleAction.new("about", None)
action.connect("activate", self.show_about)
self.add_action(action) # Here the action is being added to the window, but you could add it to the
menu.append("About", "win.about")
self.dw = Gtk.DrawingArea()
# Make it fill the available space (It will stretch with the window)
self.dw.set_hexpand(True)
self.dw.set_vexpand(True)
# Instead, If we didn't want it to fill the available space but wanted a fixed size
#dw.set_content_width(100)
#dw.set_content_height(100)
self.dw.set_draw_func(self.draw, None)
self.box3.append(self.dw)
#evc = Gtk.EventController.key_new()
evk = Gtk.GestureClick.new()
evk.connect("pressed", self.dw_click) # could be "released"
self.dw.add_controller(evk)
evk = Gtk.EventControllerKey.new()
evk.connect("key-pressed", self.key_press)
self.add_controller(evk)
self.blobs = []
self.cursor_crosshair = Gdk.Cursor.new_from_name("crosshair")
self.dw.set_cursor(self.cursor_crosshair)
app = self.get_application()
sm = app.get_style_manager()
sm.set_color_scheme(Adw.ColorScheme.PREFER_DARK)
custom = Custom()
#self.box3.append(custom)
custom.set_hexpand(True)
custom.set_vexpand(True)
def show_about(self, action, param):
self.about = Gtk.AboutDialog()
self.about.set_transient_for(self)
self.about.set_modal(self)
self.about.set_authors(["Your Name"])
self.about.set_copyright("Copyright 2022 Your Full Name")
self.about.set_license_type(Gtk.License.GPL_3_0)
self.about.set_website("http://example.com")
self.about.set_website_label("My Website")
self.about.set_version("1.0")
self.about.set_logo_icon_name("org.example.example")
self.about.show()
def key_press(self, event, keyval, keycode, state):
if keyval == Gdk.KEY_q and state & Gdk.ModifierType.CONTROL_MASK:
self.close()
def show_open_dialog(self, button):
self.open_dialog.show()
def open_response(self, dialog, response):
if response == Gtk.ResponseType.ACCEPT:
file = dialog.get_file()
filename = file.get_path()
print(filename)
def dw_click(self, gesture, data, x, y):
self.blobs.append((x, y))
self.dw.queue_draw() # Force a redraw
def draw(self, area, c, w, h, data):
# c is a Cairo context
# Fill background
c.set_source_rgb(0, 0, 0)
c.paint()
c.set_source_rgb(1, 0, 1)
for x, y in self.blobs:
c.arc(x, y, 10, 0, 2 * 3.1215)
c.fill()
# Draw a line
c.set_source_rgb(0.5, 0.0, 0.5)
c.set_line_width(3)
c.move_to(10, 10)
c.line_to(w - 10, h - 10)
c.stroke()
# Draw a rectangle
c.set_source_rgb(0.8, 0.8, 0.0)
c.rectangle(20, 20, 50, 20)
c.fill()
# Draw some text
c.set_source_rgb(0.1, 0.1, 0.1)
c.select_font_face("Sans")
c.set_font_size(13)
c.move_to(25, 35)
c.show_text("Test")
def print_something(self, action, param):
print("Something!")
def slider_changed(self, slider):
print(int(slider.get_value()))
def switch_switched(self, switch, state):
print(f"The switch has been switched {'on' if state else 'off'}")
def hello(self, button):
print("Hello world")
if self.check.get_active():
print("Goodbye world!")
self.close()
class MyApp(Adw.Application):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.connect('activate', self.on_activate)
def on_activate(self, app):
self.win = MainWindow(application=app)
self.win.present()
app = MyApp(application_id="com.example.GtkApplication")
app.run(sys.argv)