Hello there,
I am tinkering with wxPython, chasing an idea I have to write a
ttf font manager for Linux.
I have never used an email list before, so I am not sure if this is the
correct way to proceed. I will jump in.
WRAPPING
I don't know how to post the python code with wrapping on. I have disabled it.
The test is broken with the Enter key (Linux style). I am using Kmail so it might be horrible on Windows.
Please advise.
Can one attach (rather than paste) python code to these list emails?
PLATFORM:
Fedora Core 3 (Linux i686 AMD Athlon)
Python 2.3 and 2.4 depending on the Gods of the command-line.
wxPython, as reported by rpm -qa | grep wxPython
wxPython2.6-gtk2-unicode-2.6.3.2-fc2_py2.3
OUTLINE
I want to see the TTF fonts that I have. I don't want to install them before
I can preview them, I want to see them where they lie, on the drive on an
arbitrary path. The idea is to allow management of "groups" of fonts that can
be installed and removed in herds. If I have to design for client A then I
install all those fonts and fire-up Inkscape. After that I remove them and
install those for client B. Like that.
I have not found anything like this for Linux. On Windows, if anyone is
interested, there is a free app called "The font thing" that will do all
this.
WHERE I AM STUCK
I have hacked my way through the initial curve of wxPython. I have found a way
to draw arbitrary ttf files to a bitmap (using Python Imaging Library). I
have found how to cram that into a wxStaticBitmap. This all done by the skin
of my teeth and with google and the wxPython wiki (way cool). I have ordered
that wxPython book, but it's still floating over the Atlantic Ocean
somewhere.
I have hacked it so that I now have a wxBitmap per font preview and they
stack-up vertically in a scrolledPanel. All cool.
What I am trying to do now is make each bitmap clickable.
I want to be able to select it (have it turn inverse or blueish) so that it can be identified by
an index or an object ref or something that lets me use it.
That is where I am totally stuck. I find events in wxPy to be completely foreign to me.
I guess I was spoiled by too many years of Visual Basic! I can't seem to find which events apply to which controls.
The thing is, I have a list of the bitmaps (self.wxBitmaps) as I build them I append them to this list.
How do I point all of them to the same function (Onclick) so that they pass some kind of id or index along?
If you look at my code you will see the experiments that I have been trying.
Some are remarked, some not, they can be switched in and out.
There is a section where I focus on just one bitmap, trying to get it to call an event and to
identify itself to that handler in some way. So far no luck.
I cannot find a clear description of the form to use when assigning functions to the events,
so there is confusion about where the id goes, if it goes at all.
THE CODE
#!/usr/bin/env python2.3
#Using:
#(wxGTK, unicode, gtk2, wx-assertions-on, SWIG-1.3.27)
#Running on Python 2.3.4
import wx, os
import wx.lib.scrolledpanel as scrolled
#Requires Python Imaging Library: I have "python-imaging-1.1.4-7"
import Image, ImageFont,ImageDraw
class MainFrame(wx.Frame):
def __init__(self,parent, id,title,position,size):
wx.Frame.__init__(self,parent, id,title,position, size)
#Please insert you own path to some ttf files here:
self.fonts = self.GetFontList("/home/donn/visuals/fonts/TTFS/Z/")
#The scrollpanel with the images in it:
pansizer = wx.BoxSizer(wx.VERTICAL)
self.scrollPanel = scrolled.ScrolledPanel(self, -1, size=self.GetClientSize())
#The idea here is to have a long vertically scrolling list of font previews.
#These are PIL images converted to wxStaticBitmaps because I cannot figure out
#how to draw arbitrary fonts in wxPython that are NOT in the designated font folder (like ~/.fonts)
#Let's loop the loop
self.wxBitmaps = []
i = 0 #Trying to tack IDs onto the bitmaps, for event purposes.
for f in self.fonts:
wxb = wx.StaticBitmap(self.scrollPanel, i, self.wxTtfBitmap(f,64,"The lazy fox and so on"))
#wxb.Bind(wx.EVT_LEFT_DOWN, self.OnClick, wxb, i) #Does nothing
#wx.EVT_LEFT_DOWN(self, i, self.OnClick) #Assertion error
#self.scrollPanel.Bind(wx.EVT_LEFT_UP,self.OnClick,wxb,i) #Does nothing
wx.EVT_LEFT_UP(wxb,self.OnClick) #This at least triggers the function, but there is no id()
self.wxBitmaps.append(wxb)
#wx.EVT_LEFT_DOWN(self.wxBitmaps[i],i,self.OnClick) #Assertion error
#self.wxBitmaps[i].Bind(wx.EVT_LEFT_DOWN, self.OnClick, self.wxBitmaps[i], i)
pansizer.Add(wxb,0,wx.GROW)
i += 1
#Trying to get events from a single image.
# I Remarked the loop above when I tested this:
#self.wxb = wx.StaticBitmap(self.scrollPanel, 100, self.wxTtfBitmap(self.fonts[0],64,"Unclickable"))
#wxb.Bind(wx.EVT_LEFT_UP,self.OnClick,wxb,100) #Does nothing at all
#wx.EVT_LEFT_UP(self,100,self.OnClick) #Assertion Error
#wx.EVT_LEFT_UP(self.wxb,self.OnClick) #This at least triggers the function, but there is no id()
#wx.EVT_LEFT_UP(wxb,100,self.OnClick)#Assertion Error
#wx.EvtHandler.Connect(self,100,-1,wx.EVT_LEFT_UP,self.OnClick) #No go at all.
self.scrollPanel.SetSizer(pansizer)
self.scrollPanel.SetAutoLayout(1)
self.scrollPanel.SetupScrolling()
box = wx.BoxSizer(wx.VERTICAL)
box.Add(self.scrollPanel, 0, wx.LEFT | wx.ALL | wx.ADJUST_MINSIZE, 0)
box.Fit(self)
self.SetAutoLayout(True)
self.SetSizer(box)
wx.EVT_CLOSE(self, self.OnCloseWindow)
def OnClick(self,event):
#I can't seem to find a way to identify the particular bitmap that was clicked on.
#I would like at least an index that I can use against a list.
print event, event.GetId(),event.GetClassName(),event.GetEventType()
evobj = event.GetEventObject()
print evobj #Shows the scrollPanel! Not the wxBitmap.??
def wxTtfBitmap(self,paf,points,text):
#Any suggestions to improve this would be oh, so cool.
#Make the PIL image
font = ImageFont.truetype(paf,points)
lx,ly = font.getsize(text)
pilimage = Image.new("F",(lx,ly),256)
draw = ImageDraw.Draw(pilimage)
draw.text((0,0),text,font=font)
#PIL TO BITMAP
#1. PIL to wxIMAGE
wximage = wx.EmptyImage(lx,ly)
wximage.SetData(pilimage.convert('RGB').tostring())
#2. wxIMAGE to wxBITMAP
return wximage.ConvertToBitmap()
def OnCloseWindow(self, event):
self.Destroy()
def GetFontList(self, dir):
return [os.path.join(dir,f) for f in os.listdir(dir) if f[-4:].upper() == ".TTF"]
class App(wx.App):
def OnInit(self):
frame = MainFrame(None, -1, "wxBitmap Test", wx.DefaultPosition,(550,200))
self.SetTopWindow(frame)
frame.Show(True)
return True
app = App(0)
app.MainLoop()
THANKS
Thanks for the patience.
Donn Ingle,
South Afica.