12

I have two Python installations on my Debian Sid notebook, ⑴ the system's Python (v.2.7) with a little bunch of utility packages (including Tkinter) and ⑵ Anaconda's Python 3.

It is easy to see which (well, here how many...) fonts are available for the two Python distributions.

Python 2

>>> from Tkinter import Tk
>>> from tkFont import families
>>> Tk(); available = families()   ### Tk() is needed to have a running tcl interpreter
<Tkinter.Tk instance at 0x7f977bcbfb90>
>>> len(available)
3011

Python 3

>>> from tkinter import Tk
>>> from tkinter.font import families
>>> Tk() ; available = families()
<tkinter.Tk object .>
>>> len(available)
68

It seems to me that Anaconda's tkinter only looks at the basic X fonts that came with the distributionsee edit below.

Do you know a procedure to, alternatively

  • let Anaconda's tkinter know of the system fonts (preferred alternative) or
  • install a few fonts in the Anaconda's tree so that tkinter can use them?

tia


Edit the fonts available to Anaconda are indeed system fonts, but only the fonts that are known to xfontsel, i.e., the fonts in the font path that can be manipulated using xset.

I tried the following

$ cd ~/.fonts ; mkfontscale ; mkfontdir ; xset fp+ `pwd`

and xfontsel showed about 30 more font families. Checking with Python 3 I verified that only two font families were added to the list of available fonts (namely 'go' and 'gomono' — no 'consolas' etc) and producing a label

...
r = Tk() ; Label(r, text="Go Mono", font=('gomono', 24)).pack()

with Python 2 and Python 3 succeeded in both cases, but Debian's Python showed a nice antialiased text while the other was a (rough) bitmap rendition.

So, in a sense, I have partially answered my question, but

  1. not every font family, as shown by xfontsel, was taken up by tkinter
  2. even for the very few that were recognized, the rendition leaves too much to be desired...

and I'd like to read a better, more useful answer.

gboffi
  • 17,041
  • 5
  • 45
  • 76
  • 1
    I suspect you issue is similar to what is described in the following question: [Path to Linux Fonts in Python3 and tkinter](https://stackoverflow.com/questions/41573573/path-to-linux-fonts-in-python3-and-tkinter) – PicoutputCls Dec 12 '17 at 10:52
  • 1
    @PicoutputCls I see, the questions are similar to say the least... However I'm going to leave posted my question because I feel the question title is more up to the point and could attract more answers, what do you think? – gboffi Dec 12 '17 at 11:32
  • 1
    Agreed. I just referenced this post because I thought it might help you or someone else track down a solution to the problem. – PicoutputCls Dec 12 '17 at 11:34
  • Is there any [FONTCONFIG_PATH/FONTCONFIG_FILE](https://www.freedesktop.org/software/fontconfig/fontconfig-user.html) environment variable? Can you check something like `'FONTCONFIG_PATH' in os.environ`? – CommonSense Dec 12 '17 at 12:31
  • @CommonSense I've checked, No suitable (evidently `fontconfig` related) environment variable. – gboffi Dec 12 '17 at 12:40

2 Answers2

8

{tT}kinter works linking to a Tk/Tcl interpreter that, loosely speaking, is contained in a couple of DLL, in particular the graphical library is libtk6.0.so.

Most of the extra fonts not seen by tkinter are managed by the Freetype library and Anaconda's libtk6.0.so is not built against Freetype...

$ ldd /usr/lib/x86_64-linux-gnu/libtk8.6.so | grep freetype
        libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f0a24597000)
$ ldd miniconda3/lib/libtk8.6.so | grep freetype
$

I've tried the following, horrible thing

$ mv lib/miniconda3/lib/libtk8.6.so lib/miniconda3/lib/libtk8.6.sav
$ ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so lib/miniconda3/lib/libtk8.6.so
$ ipython
Python 3.6.3 |Anaconda, Inc.| (default, Nov 20 2017, 20:41:42) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from tkinter import Tk, Label ; from tkinter.font import families
In [2]: r = Tk() ; a = families() ; len(a)
Out[2]: 328
In [3]: r=Tk() ;  Label(r, text="Constantia", font=("Constantia", 60)).pack()
In [4]: r.mainloop()

enter image description here

Final thoughts.

  1. Substituting the DLL is not a clean solution.
  2. The fonts are not exactly the same. For sure Anaconda has its own Fontconfig subsystem and possibly the directories that are scanned are different, but I have not a correct understanding of the discrepancy in the number of fonts.
  3. The correct course of action is to persuade Anaconda, Inc. to build libtk against Freetype, but I don't know how to report to them, e.g., if I go to https://www.anaconda.com/search/issues what I see is a list of informational articles on the distribution.

Update

W.r.to point 3, I contacted via a github issue Anaconda Inc. and I was told

No we cannot do this. When building our software we need python built very early, well before anything graphical gets built. Adding Freetype as a dep for tkinter causes a cycle in the build graph and we can no longer build the distro.

Why not use something more modern than tkinter anyway?

                                                   --- Ray Donnelly (aka mingwandroid)

gboffi
  • 17,041
  • 5
  • 45
  • 76
  • I've found the appropriate channel and I've posted my findings in the following issue [tkinter fonts #6833](https://github.com/ContinuumIO/anaconda-issues/issues/6833) – gboffi Dec 13 '17 at 09:58
  • I posted also in [package tk appears to be built without truetype support #776](https://github.com/ContinuumIO/anaconda-issues/issues/776), that appears to be even more relevant and is (was?) tracked by a developer of the distribution. – gboffi Dec 13 '17 at 11:22
  • 5
    Wow. The reply you got is simultaneously helpful and insulting. Jeez. – erekalper Mar 21 '18 at 21:22
  • 1
    @erekalper Helpful inasmuch they make it clear that they are not going to fix the problem. On the other hand, I suspect that the merit of the answer is b.s. but I do not feel like having a discussion with a person that stands so bold on their position. – gboffi Mar 25 '18 at 12:40
-1

EDIT: As @gboffi pointed out, this solution only seems like it works, as sudo python doesn't use Anaconda's install, but rather the system default. Using the full Anaconda Python path with sudo still yields the limited font options. I'm going to keep exploring this, but this answer as it stands is clearly incorrect.


I was having almost the exact same problem, and the "fix" for me was to run Anaconda's Python with sudo. Doing so apparently gives it access to the rest of the fonts that, for whatever reason, it doesn't natively have. (Found this info in a sparsely populated Google Groups discussion.)

For reference, my system is running Ubuntu 16.04, and Anaconda 4.4.8 with Python 3.6.4.

python my_script.py yields:

Font families without sudo

while sudo python my_script.py yields:

Font families with sudo

Oddly they don't overlap, but I'm frustrated enough with Anaconda at this point that I'm done investigating for now. Hope this (maybe) helps! It's a bad solution that's good enough for testing.

erekalper
  • 799
  • 7
  • 20
  • `sudo python script` runs the system's Python, that is correctly built against fontconfig and truetype. I'm afraid that I cannot upvote your answer... – gboffi Mar 23 '18 at 23:16
  • You're absolutely correct; this is a total oversight on my part (and rather foolish to boot). I'm going to keep exploring this, but will update my answer. – erekalper Mar 26 '18 at 12:09