Does anybody can publish an example for using unicode with Panda?
This code doesn’t work:
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from direct.gui.DirectGui import *
from pandac.PandaModules import *
from direct.gui.OnscreenText import OnscreenText
class World(DirectObject):
def __init__(self):
text = TextNode('node name')
text.setText(u'\u041F\u0440\u0438\u0432\u0435\u0442')
text.setEncoding(2)
textNodePath = aspect2d.attachNewNode(text)
textNodePath.setScale(0.07)
w = World()
run()
An error is:
>ppython utf.py
DirectStart: Starting the game.
Warning: DirectNotify: category 'Interval' already exists
Known pipe types:
wdxGraphicsPipe8
(3 aux display modules not yet loaded.)
Traceback (most recent call last):
File "utf.py", line 16, in ?
w = World()
File "utf.py", line 11, in __init__
text.setText(u'\u041F\u0440\u0438\u0432\u0435\u0442')
File "TextNode", line 5045, in setText
File "TextNode", line 1400, in __overloaded_setText_ptrTextNode_atomicstring
UnicodeError: ASCII encoding error: ordinal not in range(128)
Panda does not (currently) accept the Python Unicode objects directly, but you can use Python’s codecs mechanism to encode them to utf-8 (or pre-encode them yourself). Note that the default Panda built-in font does not include definitions for Cyrillic characters, so you will have to load your own font:
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from direct.gui.DirectGui import *
from pandac.PandaModules import *
from direct.gui.OnscreenText import OnscreenText
import codecs
class World(DirectObject):
def __init__(self):
font = loader.loadFont('/c/WINDOWS/Fonts/msmincho.ttc')
text = TextNode('node name')
text.setFont(font)
text.setEncoding(TextNode.EUtf8)
ustr = u'\u041F\u0440\u0438\u0432\u0435\u0442'
text.setText(codecs.utf_8_encode(ustr)[0])
textNodePath = aspect2d.attachNewNode(text)
textNodePath.setScale(0.07)
w = World()
run()
On reflection, you can set up Python to automatically convert its Unicode strings into utf-8 for Panda. To do this, you must create a special file called sitecustomize.py which must be located in some directory your python path (for instance, in the current directory). Python will search file this file on startup and load it automatically (and silently) if it is found. Put the following in this file:
import sys
sys.setdefaultencoding('utf8')
print "Encoding set to UTF8"
If you don’t see that print message at startup, you didn’t put sitecustomize.py in the right place. See www.python.org for more information about sitecustomize.py and setdefaultencoding().
You can also automatically configure Panda to select utf-8 by default, and even to use a suitable font by default. Put the following in your Config.prc file:
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from direct.gui.DirectGui import *
from pandac.PandaModules import *
from direct.gui.OnscreenText import OnscreenText
class World(DirectObject):
def __init__(self):
text = TextNode('node name')
text.setText(u'\u041F\u0440\u0438\u0432\u0435\u0442')
textNodePath = aspect2d.attachNewNode(text)
textNodePath.setScale(0.07)
w = World()
run()
Of course, it would be better to supply your own font along with your application, rather than digging around in the Windows system directory (which is not in the same place on every Windows machine, and doesn’t even exist on Linux machines, of course). But loading the font out of the Windows system directory is fine for development on your own machine.
This appears to be a minor bug in the DirectGui system; it is not recognizing that the unicode text is a legitimate string. I apologize for this bug. I will put in a fix for a future version of Panda, in the meantime you can work around the bug like this:
Oops, my mistake. I understand that OnscreenText is working; I meant to use DirectButton in the above. The point is that if you wrap the str() function around your text string, DirectButton will accept it correctly.