A number of years ago I did a post on the IronPython Cookbook site about the Windows.Forms Calendar control. I could never get the thing to render nicely on *nix operating systems (BSD family). It sounds as though Windows.Forms development for mono (and in general) is kind of dead, so there is not much hope that solution/example will ever render nicely on *nix. Recently I've been playing with mono and decided to give gtk-sharp a shot with IronPython.
Quick disclaimers:
1) I suspect from the examples I've seen on the internet that PyGtk is a little easier to deal with than gtk-sharp. That's OK; I wanted to use IronPython and have the rest of the mono/dotNet framework available, so I went through the extra trouble to forego CPython and PyGtk and go with IronPython and gtk-sharp instead.
2) The desktop is not the most cutting edge or sexy platform in 2014. Nonetheless, where I work it is alive and well. When I no longer see engineers hacking solutions in Excel and VBA, I'll consider the possibility of outliving the desktop. Right now I'm not hopeful :-\
The results aren't bad, at least as far as rendering goes. I couldn't get the Courier font to take on OpenBSD, but the Gtk Calendar control looks acceptable. All in all, I was OK with the results on both Windows and OpenBSD. I've heard Gtk doesn't do quite as well on Apple products, but I don't own a Mac to test with. Here are a couple screenshots:
I run the cwm window manager on OpenBSD and have it set up to cut out borders on windows, hence the more minimalist look to the control there.
IronPython output on *nix has always come out in yellow or white - it doesn't show up on a white background, which I prefer. In order to get around this, I run an xterm with a black background:
xterm -bg black -fg white
Here is the code for the gtk-sharp Gtk.Calendar control:
#!/usr/local/bin/mono /home/carl/IronPython-2.7.4/ipy64.exe
import clr
GTKSHARP = 'gtk-sharp'
PANGO = 'pango-sharp'
clr.AddReference(GTKSHARP)
clr.AddReference(PANGO)
import Gtk
import Pango
import datetime
TITLE = 'Gtk.Calendar Demo'
MARKUP = '<span font="Courier New" size="14" weight="bold">{:s}</span>'
MARKEDUPTITLE = MARKUP.format(TITLE)
INFOMSG = '<span font="Courier New 12">\n\n Program set to run for:\n\n '
INFOMSG += '{:%Y-%m-%d}\n\n</span>'
DATEDIFFMSG = '<span font="Courier New 12">\n\n '
DATEDIFFMSG += 'There are {0:d} days between the\n'
DATEDIFFMSG += ' beginning of the epoch and\n'
DATEDIFFMSG += ' {1:%Y-%m-%d}.\n\n</span>'
ALIGNMENTPARAMS = (0.0, 0.5, 0.0, 0.0)
WINDOWWIDTH = 350
CALENDARFONT = 'Courier New Bold 12'
class CalendarTest(object):
inthebeginning = datetime.datetime.fromtimestamp(0)
# Debug info - make sure beginning of epoch really
# is +midnight, Jan 1, 1970 GMT.
print(inthebeginning)
def __init__(self):
Gtk.Application.Init()
self.window = Gtk.Window(TITLE)
# DeleteEvent - copied from Gtk demo on internet.
self.window.DeleteEvent += self.DeleteEvent
# Frame property provides a frame and title.
self.frame = Gtk.Frame(MARKEDUPTITLE)
self.calendar = Gtk.Calendar()
# Handles date selection event.
self.calendar.DaySelected += self.dateselect
# Sets up text for labels.
self.getcaltext()
# Puts little box around text.
self.datelabelframe = Gtk.Frame()
# Try to get datelabel to align with other label.
self.datelabelalignment = Gtk.Alignment(*ALIGNMENTPARAMS)
self.datelabel = Gtk.Label(self.caltext)
self.datelabelalignment.Add(self.datelabel)
self.datelabelframe.Add(self.datelabelalignment)
# Puts little box around text.
self.datedifflabelframe = Gtk.Frame()
self.datedifflabelalignment = Gtk.Alignment(*ALIGNMENTPARAMS)
self.datedifflabel = Gtk.Label(self.timedifftext)
self.datedifflabelalignment.Add(self.datedifflabel)
self.datedifflabelframe.Add(self.datedifflabelalignment)
self.vbox = Gtk.VBox()
self.vbox.PackStart(self.datelabelframe)
self.vbox.PackStart(self.datedifflabelframe)
self.vbox.PackStart(self.calendar)
self.frame.Add(self.vbox)
self.window.Add(self.frame)
self.prettyup()
self.window.ShowAll()
# Keep text viewable - size no smaller than intended.
self.window.AllowShrink = False
Gtk.Application.Run()
def getcaltext(self):
"""
Get messages for run date.
"""
# Calendar month is 0 based.
yearmonthday = self.calendar.Year, self.calendar.Month + 1, self.calendar.Day
chosendate = datetime.datetime(*yearmonthday)
self.caltext = INFOMSG.format(chosendate)
# For reporting of number of days since beginning of epoch.
timediff = chosendate - CalendarTest.inthebeginning
self.timedifftext = DATEDIFFMSG.format(timediff.days, chosendate)
def usemarkup(self):
"""
Refreshes UseMarkup property on widgets (labels)
so that they display properly and without
markup text.
"""
# Have to refresh this property each time.
self.frame.LabelWidget.UseMarkup = True
self.datelabel.UseMarkup = True
self.datedifflabel.UseMarkup = True
def prettyup(self):
"""
Get Gtk objects looking the way we
intended.
"""
# Try to make frame wider.
# XXX
# Works nicely on Windows - try on Unix.
# Allows bold, etc.
self.usemarkup()
self.frame.SetSizeRequest(WINDOWWIDTH, -1)
# Get rid of line in middle of text on title.
self.frame.Shadow = Gtk.ShadowType.None
# Try to get Courier New on calendar.
fd = Pango.FontDescription.FromString(CALENDARFONT)
self.calendar.ModifyFont(fd)
self.datelabel.Justify = Gtk.Justification.Left
self.datedifflabel.Justify = Gtk.Justification.Left
self.window.Title = ''
self.usemarkup()
def dateselect(self, widget, event):
self.getcaltext()
self.datelabel.Text = self.caltext
self.datedifflabel.Text = self.timedifftext
self.prettyup()
def DeleteEvent(self, widget, event):
Gtk.Application.Quit()
if __name__ == '__main__':
CalendarTest()
Thanks for stopping by.
No comments:
Post a Comment