Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3707441

Browse files
authored
Merge pull request #20321 from QuLogic/gtk4
Add a GTK4 backend.
2 parents ce7e2e0 + 04f17f8 commit 3707441

27 files changed

+1312
-212
lines changed

.flake8

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,12 @@ per-file-ignores =
123123
examples/ticks_and_spines/date_concise_formatter.py: E402
124124
examples/user_interfaces/embedding_in_gtk3_panzoom_sgskip.py: E402
125125
examples/user_interfaces/embedding_in_gtk3_sgskip.py: E402
126-
examples/user_interfaces/gtk_spreadsheet_sgskip.py: E402
126+
examples/user_interfaces/embedding_in_gtk4_panzoom_sgskip.py: E402
127+
examples/user_interfaces/embedding_in_gtk4_sgskip.py: E402
128+
examples/user_interfaces/gtk3_spreadsheet_sgskip.py: E402
129+
examples/user_interfaces/gtk4_spreadsheet_sgskip.py: E402
127130
examples/user_interfaces/mpl_with_glade3_sgskip.py: E402
128-
examples/user_interfaces/pylab_with_gtk_sgskip.py: E402
131+
examples/user_interfaces/pylab_with_gtk3_sgskip.py: E402
132+
examples/user_interfaces/pylab_with_gtk4_sgskip.py: E402
129133
examples/user_interfaces/toolmanager_sgskip.py: E402
130134
examples/userdemo/pgf_preamble_sgskip.py: E402

doc/api/backend_gtk4_api.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
**NOTE** These backends are not documented here, to avoid adding a dependency
2+
to building the docs.
3+
4+
.. redirect-from:: /api/backend_gtk4agg_api
5+
.. redirect-from:: /api/backend_gtk4cairo_api
6+
7+
8+
:mod:`matplotlib.backends.backend_gtk4agg`
9+
==========================================
10+
11+
.. module:: matplotlib.backends.backend_gtk4agg
12+
13+
:mod:`matplotlib.backends.backend_gtk4cairo`
14+
============================================
15+
16+
.. module:: matplotlib.backends.backend_gtk4cairo

doc/api/index_backend_api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
backend_agg_api.rst
1111
backend_cairo_api.rst
1212
backend_gtk3_api.rst
13+
backend_gtk4_api.rst
1314
backend_nbagg_api.rst
1415
backend_pdf_api.rst
1516
backend_pgf_api.rst

doc/devel/dependencies.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ and the capabilities they provide.
4242

4343
* Tk_ (>= 8.4, != 8.6.0 or 8.6.1) [#]_: for the Tk-based backends.
4444
* PyQt6_ (>= 6.1), PySide6_, PyQt5_, or PySide2_: for the Qt-based backends.
45-
* PyGObject_: for the GTK3-based backends [#]_.
45+
* PyGObject_: for the GTK-based backends [#]_.
4646
* wxPython_ (>= 4) [#]_: for the wx-based backends.
47-
* pycairo_ (>= 1.11.0) or cairocffi_ (>= 0.8): for the GTK3 and/or cairo-based
47+
* pycairo_ (>= 1.11.0) or cairocffi_ (>= 0.8): for the GTK and/or cairo-based
4848
backends.
4949
* Tornado_: for the WebAgg backend.
5050

examples/user_interfaces/embedding_in_gtk3_panzoom_sgskip.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
win = Gtk.Window()
2121
win.connect("delete-event", Gtk.main_quit)
2222
win.set_default_size(400, 300)
23-
win.set_title("Embedding in GTK")
23+
win.set_title("Embedding in GTK3")
2424

2525
fig = Figure(figsize=(5, 4), dpi=100)
2626
ax = fig.add_subplot(1, 1, 1)

examples/user_interfaces/embedding_in_gtk3_sgskip.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
win = Gtk.Window()
2020
win.connect("delete-event", Gtk.main_quit)
2121
win.set_default_size(400, 300)
22-
win.set_title("Embedding in GTK")
22+
win.set_title("Embedding in GTK3")
2323

2424
fig = Figure(figsize=(5, 4), dpi=100)
2525
ax = fig.add_subplot()
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""
2+
===========================================
3+
Embedding in GTK4 with a navigation toolbar
4+
===========================================
5+
6+
Demonstrate NavigationToolbar with GTK4 accessed via pygobject.
7+
"""
8+
9+
import gi
10+
gi.require_version('Gtk', '4.0')
11+
from gi.repository import Gtk
12+
13+
from matplotlib.backends.backend_gtk4 import (
14+
NavigationToolbar2GTK4 as NavigationToolbar)
15+
from matplotlib.backends.backend_gtk4agg import (
16+
FigureCanvasGTK4Agg as FigureCanvas)
17+
from matplotlib.figure import Figure
18+
import numpy as np
19+
20+
21+
def on_activate(app):
22+
win = Gtk.ApplicationWindow(application=app)
23+
win.set_default_size(400, 300)
24+
win.set_title("Embedding in GTK4")
25+
26+
fig = Figure(figsize=(5, 4), dpi=100)
27+
ax = fig.add_subplot(1, 1, 1)
28+
t = np.arange(0.0, 3.0, 0.01)
29+
s = np.sin(2*np.pi*t)
30+
ax.plot(t, s)
31+
32+
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
33+
win.set_child(vbox)
34+
35+
# Add canvas to vbox
36+
canvas = FigureCanvas(fig) # a Gtk.DrawingArea
37+
canvas.set_hexpand(True)
38+
canvas.set_vexpand(True)
39+
vbox.append(canvas)
40+
41+
# Create toolbar
42+
toolbar = NavigationToolbar(canvas, win)
43+
vbox.append(toolbar)
44+
45+
win.show()
46+
47+
48+
app = Gtk.Application(
49+
application_id='org.matplotlib.examples.EmbeddingInGTK4PanZoom')
50+
app.connect('activate', on_activate)
51+
app.run(None)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""
2+
=================
3+
Embedding in GTK4
4+
=================
5+
6+
Demonstrate adding a FigureCanvasGTK4Agg widget to a Gtk.ScrolledWindow using
7+
GTK4 accessed via pygobject.
8+
"""
9+
10+
import gi
11+
gi.require_version('Gtk', '4.0')
12+
from gi.repository import Gtk
13+
14+
from matplotlib.backends.backend_gtk4agg import (
15+
FigureCanvasGTK4Agg as FigureCanvas)
16+
from matplotlib.figure import Figure
17+
import numpy as np
18+
19+
20+
def on_activate(app):
21+
win = Gtk.ApplicationWindow(application=app)
22+
win.set_default_size(400, 300)
23+
win.set_title("Embedding in GTK4")
24+
25+
fig = Figure(figsize=(5, 4), dpi=100)
26+
ax = fig.add_subplot()
27+
t = np.arange(0.0, 3.0, 0.01)
28+
s = np.sin(2*np.pi*t)
29+
ax.plot(t, s)
30+
31+
# A scrolled margin goes outside the scrollbars and viewport.
32+
sw = Gtk.ScrolledWindow(margin_top=10, margin_bottom=10,
33+
margin_start=10, margin_end=10)
34+
win.set_child(sw)
35+
36+
canvas = FigureCanvas(fig) # a Gtk.DrawingArea
37+
canvas.set_size_request(800, 600)
38+
sw.set_child(canvas)
39+
40+
win.show()
41+
42+
43+
app = Gtk.Application(application_id='org.matplotlib.examples.EmbeddingInGTK4')
44+
app.connect('activate', on_activate)
45+
app.run(None)

examples/user_interfaces/gtk_spreadsheet_sgskip.py renamed to examples/user_interfaces/gtk3_spreadsheet_sgskip.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
2-
===============
3-
GTK Spreadsheet
4-
===============
2+
================
3+
GTK3 Spreadsheet
4+
================
55
66
Example of embedding Matplotlib in an application and interacting with a
77
treeview to store data. Double click on an entry to update plot data.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
"""
2+
================
3+
GTK4 Spreadsheet
4+
================
5+
6+
Example of embedding Matplotlib in an application and interacting with a
7+
treeview to store data. Double click on an entry to update plot data.
8+
"""
9+
10+
import gi
11+
gi.require_version('Gtk', '4.0')
12+
gi.require_version('Gdk', '4.0')
13+
from gi.repository import Gtk
14+
15+
from matplotlib.backends.backend_gtk4agg import FigureCanvas # or gtk4cairo.
16+
17+
from numpy.random import random
18+
from matplotlib.figure import Figure
19+
20+
21+
class DataManager(Gtk.ApplicationWindow):
22+
num_rows, num_cols = 20, 10
23+
24+
data = random((num_rows, num_cols))
25+
26+
def __init__(self, *args, **kwargs):
27+
super().__init__(*args, **kwargs)
28+
self.set_default_size(600, 600)
29+
30+
self.set_title('GtkListStore demo')
31+
32+
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, homogeneous=False,
33+
spacing=8)
34+
self.set_child(vbox)
35+
36+
label = Gtk.Label(label='Double click a row to plot the data')
37+
vbox.append(label)
38+
39+
sw = Gtk.ScrolledWindow()
40+
sw.set_has_frame(True)
41+
sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
42+
sw.set_hexpand(True)
43+
sw.set_vexpand(True)
44+
vbox.append(sw)
45+
46+
model = self.create_model()
47+
self.treeview = Gtk.TreeView(model=model)
48+
self.treeview.connect('row-activated', self.plot_row)
49+
sw.set_child(self.treeview)
50+
51+
# Matplotlib stuff
52+
fig = Figure(figsize=(6, 4), constrained_layout=True)
53+
54+
self.canvas = FigureCanvas(fig) # a Gtk.DrawingArea
55+
self.canvas.set_hexpand(True)
56+
self.canvas.set_vexpand(True)
57+
vbox.append(self.canvas)
58+
ax = fig.add_subplot()
59+
self.line, = ax.plot(self.data[0, :], 'go') # plot the first row
60+
61+
self.add_columns()
62+
63+
def plot_row(self, treeview, path, view_column):
64+
ind, = path # get the index into data
65+
points = self.data[ind, :]
66+
self.line.set_ydata(points)
67+
self.canvas.draw()
68+
69+
def add_columns(self):
70+
for i in range(self.num_cols):
71+
column = Gtk.TreeViewColumn(str(i), Gtk.CellRendererText(), text=i)
72+
self.treeview.append_column(column)
73+
74+
def create_model(self):
75+
types = [float] * self.num_cols
76+
store = Gtk.ListStore(*types)
77+
for row in self.data:
78+
# Gtk.ListStore.append is broken in PyGObject, so insert manually.
79+
it = store.insert(-1)
80+
store.set(it, {i: val for i, val in enumerate(row)})
81+
return store
82+
83+
84+
def on_activate(app):
85+
manager = DataManager(application=app)
86+
manager.show()
87+
88+
89+
app = Gtk.Application(application_id='org.matplotlib.examples.GTK4Spreadsheet')
90+
app.connect('activate', on_activate)
91+
app.run()

0 commit comments

Comments
 (0)