[PyKDE] Feedback Needed on Possible tr() Changes

Detlev Offenbach detlev at die-offenbachs.de
Sun May 25 10:28:00 BST 2003


Hi,

I would rather leave the implementation as it is right now. It only 
causes problems, if the subclass doesn't contain any string that needs a 
translation (i.e. no call to self.tr or self.trUtf8). For these it is 
reallly easy to include a dummy call in the __init__ method [i.e. dummy 
= self.trUft8("dummy")]. This makes the subclass work as expected and 
all the translations are there. This is some kind of a workaraound but I 
think it is less error prone than solution 3. In addition to this 
solution 3 would need quite a bit of work for porting sources (like 
eric3) and would probably break compatibility with older PyQt versions.

Regards,
Detlev

Am Samstag, 24. Mai 2003 12:37 schrieb Phil Thompson:
> I think people have hinted to me before about this, but I've only just
> properly understood the problem. I suspect that it is impossible for
> PyQt to implement QObject.tr() properly - although I may get lucky
> with SIP v4's use of metaclasses. I've made a couple of attempts in
> the past, but it seems that the current implementation may not the
> best design decision I've ever made.
>
> Translation in Qt is based on the string to translate and a context.
> The context is usually the name of the class from which tr() is
> called. Each C++ class that contains the Q_OBJECT macro has it's tr()
> method created automatically by moc. Each generated tr() has the
> proper context hardcoded. It is very difficult/impossible to emulate
> this behaviour in PyQt for Python classes that extend C++ classes.
>
> Note that there is a workaround for all this. Just use...
>
> qApp.translate("Context","String")
>
> ...instead of calls to tr().
>
> At the moment I see 3 options...
>
> 1. Current Unpredictable Option
> The current implementation uses the name of the class of the instance
> as the context. The problem is then that, if the class is further
> sub-classed, the context changes. An example (ignoring calls to
> __init__)...
>
> class A(QObject):
> 	def hello(self):
> 		return self.tr("Hello")
>
> class B(A):
> 	pass
>
> class C(A):
> 	pass
>
> a = A().hello()	# Context is "A"
> b = B().hello()	# Context is "B"
> c = C().hello()	# Context is "C"
>
> ...which requires 3 translations of the string. The problem is at its
> worse if A is a class generated by pyuic.
>
> 2. Old Predictable Option
> The original implementation had an automatically generated tr() for
> each wrapped QObject sub-class. This meant that the context was
> correct for those, but incorrect for any Python sub-class where it was
> the most recent C++ in the hierarchy. For example...
>
> class A(QObject):
> 	def hello(self):
> 		return self.tr("Hello")
>
> class B(QObject):
> 	def welcome(self):
> 		return self.tr("Hello")
>
> a = A().hello()		# Context is "QObject"
> b = B().welcome()	# Context is "QObject"
>
> ...which (I think) has the consequence of creating one string for
> translation when, perhaps, there should be two. Also, I'm not sure if
> pylupdate will determine the correct context.
>
> 3. New Clumsy Option
> Another option is to dump the problem onto the application developer.
> A Q_OBJECT() method could be added to QObject that does the same job
> as the Q_OBJECT macro and creates the tr() method with the correct
> context hardcoded. For example...
>
> class A(QObject):
> 	def __init__(self):
> 		QObject.__init__(self)
> 		self.Q_OBJECT(A)
>
> 	def hello(self):
> 		return A.tr("Hello")
>
> class B(A):
> 	def __init__(self):
> 		A.__init__(self)
> 		self.Q_OBJECT(B)
>
> 	def goodbye(self):
> 		return B.tr("Goodbye")
>
> b = B()
> b.hello()		# Context is "A"
> b.goodbye()	# Context is "B"
>
> ...but note that you must explicitly call the class specific tr() and
> not self.tr() - which I feel means you might as well call
> qApp.translate() and forget the added complexity of Q_OBJECT().
>
> Note that whatever option is used, I will fix pyuic so that generated
> forms get the context right.
>
> Each option has its advantages and disadvantages - developers are
> currently dealing with Option 1, Option 2 is probably the least
> confusing.
>
> Comments and other suggestions welcome.
>
> Phil
>
> _______________________________________________
> PyKDE mailing list    PyKDE at mats.imk.fraunhofer.de
> http://mats.imk.fraunhofer.de/mailman/listinfo/pykde

-- 
Detlev Offenbach
detlev at die-offenbachs.de




More information about the PyQt mailing list