[PyQt] PyKDE dcopext string marshalling; no unicode chars in a QString?

Danny Pansters danny at ricin.com
Mon Apr 30 15:22:12 BST 2007


Hi,

It seems I can't retrieve a QString object containing non-ASCII characters. I 
have a TV application (on FreeBSD) and it exports most of its functions via 
dcop. I now added functionality to retrieve (raw YUV) framedata over dcop, 
the idea being to eventually write a minimal dcopclient in C++ and patch that 
into Kopete to be used for webcam purposes.

The code that does the video capturing is written in C and used in the rest of 
the app as a python module (using SWIG to expose a dozen simple control 
functions). Currently, as a first starting point, I strncpy() the framebuffer 
data into a string and any calling code recieves it as such. From my DCOP 
export code: self.addMethod("QString frameData()", obj.frameData). The 
frameData method simply returns QString(my_swig_module.frame_data()).

Using the dcop cmdline utility or kdcop it seems to work alright:

%dcop kbtv Kbtv wantFrameData 1
%dcop kbtv Kbtv frameData
< lots of gibberish on the console >
%dcop kbtv Kbtv wantFrameData 0

But when trying to write a proof-of-concept in Python (most taken from dcopext 
example):

%python dcoptest.py
--------------------------
The DCOPObjects for kbtv:
Kbtv not running!

Start a kbtv instance
errcode: 0   error:    dcopService: kbtv  pid: 57545
--------------------------
Check if wantFrameData and frameData are valid functions
valid True True
--------------------------
wantFrameData's arg types and names
[[('int', 2)]] [[None]]
--------------------------
frameData's arg types and names
[[]] [[]]
--------------------------
Set wantFrameData to yes
call returns: (True, None)
--------------------------
Get frameData for a frame
call returns: (True, '')
--------------------------
Sleep for 1/2 second
--------------------------
Get frameData for another frame
call returns:
Traceback (most recent call last):
  File "dcoptest.py", line 150, in ?
    print "call returns:", o1.frameData()
  File "/usr/local/lib/python2.4/site-packages/dcopext.py", line 591, in 
__call__
    return self.dcop_call(args)
  File "/usr/local/lib/python2.4/site-packages/dcopext.py", line 611, in 
dcop_call
    return ok, self.__unmarshall(replyData, replyType)
  File "/usr/local/lib/python2.4/site-packages/dcopext.py", line 719, in 
__unmarshall
    return str(dcop_next(s, type_))
UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 
2: ordinal not in range(128)

Note that the first time there is no framedata yet. I realize that this is 
because of how the auto-[un]marshalling works. Any suggestions? I'd like to 
have a simple test consumer in python so I can work out the issues of  dcop, 
RGB conversion and getting something drawn on a pixmap etc, before moving 
over to C++ (which I don't even know ;-)

Should I use another datatype instead? Note that the actual framebuffer data 
will come in the form of a char* so basically it can be treated as a ustring 
(or Array?) on the main app's python side. I don't want expensive conversions 
in the main app's code (the consumer is a different thing, it will have 
expensive operations anyway).

Thanks,

Dan


More information about the PyQt mailing list