aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB Stack <bgstack15@gmail.com>2019-06-15 15:28:52 -0400
committerB Stack <bgstack15@gmail.com>2019-06-15 15:28:52 -0400
commite51a2983fd6762ca3357cca8a7b63e7b0a0376fb (patch)
tree2e49e9a524f8c8844a4b9adfa773d4c1d1468340
parentadd ref for svg for tkinter (diff)
downloadlogout-manager-rsvg-and-cairo.tar.gz
logout-manager-rsvg-and-cairo.tar.bz2
logout-manager-rsvg-and-cairo.zip
WIP: try with rsvg and cairorsvg-and-cairo
Unfortunately I just couldn't get the examples working with rsvg and cairo, so I will have to try something else. References: http://code.activestate.com/lists/python-list/595078/ https://grokbase.com/t/python/python-list/112fsd3tyw/displaying-svg-in-tkinter-using-cairo-and-rsvg
-rwxr-xr-xlogout-manager-tcl.py18
-rwxr-xr-xsample.py175
2 files changed, 186 insertions, 7 deletions
diff --git a/logout-manager-tcl.py b/logout-manager-tcl.py
index cfeb851..0a0a1f7 100755
--- a/logout-manager-tcl.py
+++ b/logout-manager-tcl.py
@@ -29,11 +29,8 @@
# tkinter: python36-tkinter | python3-tk
# PIL: python36-pillow-tk | python3-pil.imagetk
# cairo: python36-cairo | python3-cairo
-# Rsvg: python36-gobject | python3-gobject
+# Rsvg: python36-gobject | gir1.2-rsvg-3.0
-from gi import require_version
-require_version('Rsvg', '2.0')
-from gi.repository import Rsvg
import os, sys, configparser, glob, re, cairo
import tkinter as tk
import tkinter.ttk as ttk
@@ -42,6 +39,11 @@ from pathlib import Path
from PIL import Image, ImageTk
sys.path.append("/home/bgirton/dev/logout-manager")
import lmlib
+WITH_SVG=True
+if not WITH_SVG is None and WITH_SVG:
+ from gi import require_version
+ require_version('Rsvg', '2.0')
+ from gi.repository import Rsvg as rsvg
#if TkVersion < 8.6:
# USE_PRIVATE_TCL_IMAGES = 1
# print("Loading private PIL translation layter")
@@ -86,7 +88,7 @@ def convert(bgra_buffer, width, height):
def photoimage_from_svg(file_path_name):
'''Return a Tkinter.PhotoImage with the content set to the rendered SVG.'''
- svg = rsvg.Handle(file=file_path_name)
+ svg = rsvg.Handle(file_path_name)
width, height = svg.get_dimension_data()[:2]
surface = cairo.ImageSurface(cairo.FORMAT_RGB24, int(width), int(height))
context = cairo.Context(surface)
@@ -349,8 +351,10 @@ def get_scaled_icon(icon_name, size = 24, icon_theme = "default", fallback_icon_
photo = photoimage_from_svg(iconfilename)
else:
photo = Image.open(iconfilename)
- except:
- print("Error with icon file.")
+ except Exception as e:
+ print("Error with icon file:",e)
+ if "gobject" in str(e):
+ raise
return None
# If I ever add HiDPI stuff, multiple size here by the factor. So, size * 1.25
photo.thumbnail(size=[size, size])
diff --git a/sample.py b/sample.py
new file mode 100755
index 0000000..7ad8f07
--- /dev/null
+++ b/sample.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python3
+# File: sample.py
+# License: CC-BY-SA 4.0
+# Author: bgstack15
+# Startdate: 2019-06-14 17:42
+# Title: Learning how to display an svg in tcl/tk with python
+# Purpose:
+# History:
+# Usage:
+# References:
+# rsvg https://stackoverflow.com/questions/10393675/rsvg-with-python-3-2-on-ubuntu/19744099#19744099
+# svg for tkinter http://code.activestate.com/lists/python-list/595078/
+# Improve:
+# add svg support
+# Dependencies:
+# package: RPM | DPKG
+# tkinter: python36-tkinter | python3-tk
+# PIL: python36-pillow-tk | python3-pil.imagetk
+# cairo: python36-cairo | python3-cairo
+# Rsvg: python36-gobject | gir1.2-rsvg-3.0
+
+import os, sys, configparser, glob, re, cairo
+import tkinter as tk
+import tkinter.ttk as ttk
+from functools import partial
+from pathlib import Path
+from PIL import Image, ImageTk
+sys.path.append("/home/bgirton/dev/logout-manager")
+import lmlib
+import inspect # here for troubleshooting sample.py only
+WITH_SVG=True
+if not WITH_SVG is None and WITH_SVG:
+ from gi import require_version
+ require_version('Rsvg', '2.0')
+ from gi.repository import Rsvg as rsvg
+#if TkVersion < 8.6:
+# USE_PRIVATE_TCL_IMAGES = 1
+# print("Loading private PIL translation layter")
+# def PhotoImage_from_png(file):
+# return ImageTk.PhotoImage(file=file)
+
+config = lmlib.Initialize_config()
+actions = lmlib.Actions
+
+# graphical classes and functions
+print("Loading graphics...")
+
+def _alpha_blending(rgba, back):
+ "Return a rgb tuple composed from a rgba and back(ground) tuple/list."
+ paired = zip(rgba[:-1], back)
+ alpha = rgba[-1]
+ tmp = list()
+ for upper, lower in paired:
+ blend = int((((255 - alpha) * lower) + (alpha * upper)) / 255)
+ tmp.append(blend)
+
+ return(tuple(tmp))
+
+def convert(bgra_buffer, width, height):
+ "Convert bgra buffer to photoimage put"
+ idx = 0
+ end = len(bgra_buffer)
+ arguments = list()
+
+ while idx < end:
+ rgba = (ord(str(bgra_buffer[idx + 2])),
+ ord(str(bgra_buffer[idx + 1])),
+ ord(str(bgra_buffer[idx + 0])),
+ ord(str(bgra_buffer[idx + 3])))
+ back = (255, 255, 255)
+ rgb = _alpha_blending(rgba, back)
+ arguments += rgb
+ idx += 4
+
+ template = ' '.join(height *['{%s}' % (''.join(width*["#%02x%02x%02x"]))])
+ #print(template)
+ #print(arguments[-1])
+ return(template % tuple(arguments))
+
+def photoimage_from_svg(file_path_name):
+ '''Return a Tkinter.PhotoImage with the content set to the rendered SVG.'''
+ svg = rsvg.Handle()
+ svg.new_from_file(file_name=file_path_name)
+
+ #print(svg)
+ #print(inspect.getmembers(rsvg.Handle))
+ #svg.open(file=file_path_name)
+
+ #print(svg.height)
+ #print(svg.get_dimensions().height)
+ #print(inspect.getmembers(rsvg.DimensionData))
+
+ #width, height = svg.get_dimensions()[:2]
+ width, height = [48,48]
+ surface = cairo.ImageSurface(cairo.FORMAT_RGB24, int(width), int(height))
+ context = cairo.Context(surface)
+ svg.render_cairo(context)
+ image = tk.PhotoImage(width=width, height=height)
+ data = convert(surface.get_data(), width, height)
+ image.put(data)
+ return(image)
+
+def get_scaled_icon(icon_name, size = 24, icon_theme = "default", fallback_icon_name = ""):
+ iconfilename = None
+
+ # assume icon_name is file.
+ iconfilename = icon_name
+
+ # So now that we think we have derived the correct filename...
+ photo = photoimage_from_svg(iconfilename)
+ #try:
+ # print("Trying svg file",iconfilename)
+ # # try an svg
+ # if re.compile(".*\.svg").match(iconfilename):
+ # print("Trying svg...")
+ # photo = photoimage_from_svg(iconfilename)
+ #except Exception as e:
+ # print("Error with icon file:",e)
+ # if "gobject" in str(e):
+ # raise
+ # return None
+ photo.thumbnail(size=[size, size])
+ try:
+ photo2 = ImageTk.PhotoImage(photo)
+ except Exception as e:
+ print("Error was ",e)
+ return photo2
+
+class App:
+ def __init__(self, master):
+ frame = tk.Frame(master)
+ frame.grid(row=0)
+
+ self.buttonLock = tk.Button(frame, text="Lock", underline=3, command=partial(actions.lock,config))
+ self.buttonLock.grid(row=0,column=0)
+ # WORKS master.bind_all("<Alt-k>", something)
+ # PASSES 2 params when expecting 1 master.bind_all("<Alt-k>", self.buttonLock.invoke)
+ master.bind_all("<Alt-k>", partial(actions.lock,config))
+
+ # WORKS, for basic image loading.
+ self.photoLogout = get_scaled_icon(config.get_logout_icon(), config.get_icon_size(), config.get_icon_theme())
+ self.buttonLogout = tk.Button(frame, text="Logout", underline=0, command=lambda: actions.logout(config), image=self.photoLogout, compound=tk.LEFT)
+ master.bind_all("<Alt-l>", partial(actions.logout,config))
+ Tooltip(self.buttonLogout, text="HERE IS SOMETHING!")
+ self.buttonLogout.grid(row=0,column=1)
+
+ #self.buttonCancel = tk.Button(frame, text="Cancel", underline=0, command=frame.quit)
+ self.buttonCancel = tk.Button(frame, text="Cancel", underline=0, command=self.quitaction)
+ self.buttonCancel.grid(row=1,columnspan=8,sticky=tk.W+tk.E)
+ master.bind_all("<Alt-c>", self.quitaction)
+
+ # Found this after trial and error.
+ def quitaction(self,b=None):
+ print("Cancel any logout action.")
+ root.destroy()
+
+# Left here as an example for a mster.bind_all that works.
+#def something(event=None):
+# print("Got here!")
+
+root = tk.Tk()
+
+# MAIN LOOP
+root.title("Log out options")
+imgicon = get_scaled_icon("/usr/share/icons/Numix/96/actions/system-shutdown.svg",24)
+
+print(imgicon)
+
+root.tk.call('wm','iconphoto', root._w, imgicon)
+app = App(root)
+root.mainloop()
+try:
+ root.destroy()
+except:
+ pass
bgstack15