gnue-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnue-dev] Unicode + wxPython


From: Arturas Kriukovas
Subject: [Gnue-dev] Unicode + wxPython
Date: Fri, 23 Aug 2002 13:39:41 +0200
User-agent: Mutt/1.3.28i

Hello


some time ago i thought that wxPython does not support unicode. But with
a help from Jan & Codeworks guru Marius appeared, that it's possible to
get unicode wxForm via wxPython. Full sequence of achieving this is
written below. However, the main thing is that with currect outer
software (on my system it is Python 2.1.3, wxPython 2.2) we can see
unicode characters and should be able to support them.


Arturas
address@hidden
address@hidden


How to put unicode characters in GNUE form:
1. Getting unicode console.
My usual system locale configuration is:
    >locale
    LANG=POSIX
    LC_CTYPE="lt_LT.ISO8859-13"
    LC_NUMERIC="lt_LT.ISO8859-13"
    LC_TIME="lt_LT.ISO8859-13"
    LC_COLLATE="lt_LT.ISO8859-13"
    LC_MONETARY="lt_LT.ISO8859-13"
    LC_MESSAGES="lt_LT.ISO8859-13"
    LC_PAPER="lt_LT.ISO8859-13"
    LC_NAME="lt_LT.ISO8859-13"
    LC_ADDRESS="lt_LT.ISO8859-13"
    LC_TELEPHONE="lt_LT.ISO8859-13"
    LC_MEASUREMENT="lt_LT.ISO8859-13"
    LC_IDENTIFICATION="lt_LT.ISO8859-13"
    LC_ALL=lt_LT.ISO8859-13
    >locale charmap
    ISO-8859-13
On your system it will of course be different, but not too much.
Too main variables here are:
 * LC_CTYPE and
 * LC_ALL.
LC_ALL is important because it overrides all other LC_* variables - any
changes to LC_CTYPE will not work if LC_ALL will be set to some value.
LC_CTYPE defines your 'character classification' (from manual; as far as
i saw it practically defines what key on your keyboard what letter
define).
We need to unset LC_ALL (because it will override LC_CTYPE and we do not
need this) and change LC_CTYPE to some utf-8 value. I do it like this:
    unset LC_ALL
    LC_CTYPE=lt_LT.UTF-8
After running it my locale configuration becomes like this:
    >unset LC_ALL
    address@hidden:11:22:38:~:
    >LC_CTYPE=lt_LT.UTF-8
    address@hidden:11:22:57:~:
    >locale
    LANG=POSIX
    LC_CTYPE=lt_LT.UTF-8
    LC_NUMERIC="POSIX"
    LC_TIME="POSIX"
    LC_COLLATE=C
    LC_MONETARY="POSIX"
    LC_MESSAGES="POSIX"
    LC_PAPER="POSIX"
    LC_NAME="POSIX"
    LC_ADDRESS="POSIX"
    LC_TELEPHONE="POSIX"
    LC_MEASUREMENT="POSIX"
    LC_IDENTIFICATION="POSIX"
    LC_ALL=
    address@hidden:11:23:00:~:
    >locale charmap
    UTF-8
Now with current locale configuration we need to start xterm. Note that
we also need to set specific font font xterm, what can be done:
    xterm -fn -misc-fixed-medium-*-140-*-iso10646-1 
        -fb -misc-fixed-medium-*-140-*-iso10646-1 &
[there shouldn't be a line break before '-fb' - all command should be in
one line - this break is for better readability]
The parameters for xterm set it to use misc fixed .... font, the most
important thing here is font encoding - iso10646-1 - it is ISO unicode
font encoding name.
Personally i use a small script:
        #!/bin/bash
        old_CTYPE=$LC_CTYPE
        old_ALL=$LC_ALL
        LC_CTYPE=lt_LT.UTF-8
        unset LC_ALL
        command xterm -fn -misc-fixed-medium-*-140-*-iso10646-1 -fb
            -misc-fixed-medium-*-140-*-iso10646-1 &
        LC_CTYPE=$old_CTYPE
        LC_ALL=$old_ALL
['command' is used because i have an alias 'xterm' to launch xterm with
Lithuanian fonts]
Now we have unicode xterm.

2. Switching through languages.
In my .xsession file i have following settings:
        export LC_CTYPE=lt_LT.ISO8859-13
        export LC_COLLATE=lt_LT.ISO8859-13
        export LC_ALL=lt_LT.ISO8859-13
        setxkbmap -option grp:alt_shift_toggle lt &
This binds LeftAlt + LeftShift buttons to change between English and
Lithuanian languages.
When i have unicode xterm, i simply run commands like 'setxkbmap ru', or
'setxkbmap de' or any other and use LeftAlt+LeftShift to switch between
English and the language i set up.

So now we have unicode xterm and we can write there in different
languages.

3. Work.
We can work as well from unicode console as well as from simple console.
The only note - if we save file from unicode console that has some
non-standard characters (i mean characters that are specific to some 
languages, the ones that are not in ASCII [English language does not
have these]) and later try to open this file from simple (non-unicode)
console, we will not see these characters (this is important thing as we'll see
later).
This is because the file is saved encoded in UTF - that is ASCII
characters are saved in one byte encoding, other characters are saved in
two or more bytes.

4. Python.
This is a simple python script (also included as attachment) that should
be saved as UTF encoded file, let's say as 'script1.py':
    #!/usr/bin/python
    print "UTF-8 & one byte font"
    print "---------------------"
    print "Creating unicode string 'foo'"
    foo = unicode('asd--[russian letters]-[lithuanian letters]','utf-8')
    print "String output encoded in UTF-8: print foo.encode('utf-8')"
    print foo.encode('utf-8')
    print "String output as ASCII: print foo"
    print foo
You can write any non-ASCII characters instead of [russian|lithuanian
letters].
If we run this file from simple (non-unicode) console, first line is not
outputted correctly and python dies trying to output second line with
ASCII decoding error.
less command does not output file correctly.
If we run this file from unicode console, first line is outputted
correctly and python dies trying to output second line with ASCII
decoding error.
less command here does output file correctly.

5. wxPython
This is a larger python script, that i shamelessly copied from
somewhere.
It also should be saved as UTF-8 encoded file, let's say as
'script2.py'.
It has a window, some labels, menu, status bar, button... :
NOTE: you might not see characters correctly - it's because your window
manager uses some not-unicode encoding. I cannot tell you now what\where
to change - it's too window manager dependent, however every font that
is used, should be encoded as ...iso10646-1, not as iso8859-*
not this:
-->  -*-*-*-*-*-*-*-*-*-*-*-*-iso8859-1
but this:
-->  -*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1

-------------------------------BEGIN------------------------------------
#!/usr/bin/python
#---------------------------------------------
# Name:         Cookie.Py
# Purpose:      A silly `fortune' application
#---------------------------------------------
## import all of the wxPython GUI package
from wxPython.wx             import *

## Create a new frame class, derived from the wxPython Frame.
enc = 'utf-8'
class MyFrame(wxFrame):
    def __init__(self, parent, id, title):
        self.myFortunes = [
            unicode("A fox -[russian characters]",enc).encode(enc),
            unicode("A good -[russian characters]",enc).encode(enc),
            unicode("A man -[russian characters]",enc).encode(enc) +\
            unicode("he is -[russian characters]",enc).encode(enc),
            ]
        self.which = 0
        myMenuTable = (
            [unicode('&File-[russian characters]',enc).encode(enc),
             (unicode('&New-[russian characters]',enc).encode(enc),
unicode('Get a -[russian characters]',enc).encode(enc),
self.OnButtonClick),
             ('---',),
             (unicode('E&xit-[russian characters]',enc).encode(enc),
unicode('Leave -[russian characters]',enc).encode(enc), self.exitApp)],
            )
        # Call the parent class method
        wxFrame.__init__(self, parent, id, title,
                         wxPoint(100, 100), wxSize(160, 100))
        # Add a panel to place things in
        panel = wxPanel(self, -1)
        self.text = wxStaticText(panel, 1009, \
                     "Click on button to get a cookie!", \
                      wxPoint(40,25), wxSize(150,80))
        button = wxButton(self, 1010, "New cookie", \
                          wxPoint(150,90), wxSize(70,20))
        # window layout
        box = wxBoxSizer(wxVERTICAL)
        spacer = wxBoxSizer(wxHORIZONTAL)
        spacer.Add(0, 0, 1, wxEXPAND)
        spacer.Add(button, 0, wxALIGN_BOTTOM)
        spacer.Add(0, 0, 1, wxEXPAND)
        box.Add(panel, 1, wxEXPAND)
        box.Add(spacer, 0, wxEXPAND)
        # associate button with event
        EVT_BUTTON(self, 1010, self.OnButtonClick)
        # associate close event with handling method
        EVT_CLOSE(self, self.OnCloseWindow)
        # make a status bar
        self.CreateStatusBar()
        # Make a main menu
        self.mainmenu = wxMenuBar()
        # fill the `file menu table'
        for submenu in myMenuTable:
            newMenu = wxMenu()
            for item in submenu[1:]:
                if (item[0] != '---'):
                    fmID = NewId()
                    newMenu.Append(fmID, item[0], item[1])
                    EVT_MENU(self, fmID, item[2])
                else:
                    newMenu.AppendSeparator()
            # fill the main menu
            self.mainmenu.Append(newMenu, submenu[0])
        self.SetMenuBar(self.mainmenu)
        self.Fit()
        self.SetSizer(box)
        self.SetAutoLayout(true)
    def OnButtonClick(self, event):
        self.text.SetLabel(self.myFortunes[self.which \
                    % len(self.myFortunes)])
        self.which = self.which + 1
    # This method is called automatically when the CLOSE event is
    # sent to this window
    def OnCloseWindow(self, event):
        ruSure=wxMessageDialog(self, "Do you want to quit?",\
                   "Leaving Cookie", \
                   wxOK | wxCANCEL | wxICON_QUESTION)
        if (ruSure.ShowModal() == wxID_CANCEL):
            event.Veto()
        else:
            print "# Bye bye [russian characters]"
            # tell the window to kill itself
            self.Destroy()
    def exitApp(self,event):
        self.Close()
# Every wxWindows application must have a class derived from wxApp
class MyApp(wxApp):
    # wxWindows calls this method to initialize the application
    def OnInit(self):
        # Create an instance of our customized Frame class
        frame = MyFrame(NULL, -1, "Cookies!")
        frame.Show(true)
        # Tell wxWindows that this is our main window
        self.SetTopWindow(frame)
        # Return a success flag
        return true
# if running standalone
if __name__ == "__main__":
    app = MyApp(0)     # Create an instance of the application class
    app.MainLoop()     # Tell it to start processing events
---------------------------------END----------------------------

We can see a nice window with some non-ASCII like characters in menu,
labels and etc.

6. GNUE.
If we run GNUE form client or designer from unicode console, we can put
English, Russian, Lithuanian and any other characters in textboxes. So
it looks like support for unicode is internal GNUE problem that should
not require any additional outer software support.

Attachment: script1.png.gz
Description: Binary data

Attachment: script1.py.gz
Description: Binary data

Attachment: script2.png.gz
Description: Binary data

Attachment: script2.py.gz
Description: Binary data

Attachment: pgpPFX5sladkv.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]