[PyKDE] Feedback Needed on Possible tr() Changes

Phil Thompson phil at riverbankcomputing.co.uk
Mon May 26 15:36:00 BST 2003


On Sunday 25 May 2003 9:27 am, Detlev Offenbach wrote:
> 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

I don't understand how the dummy call makes any difference at all. The context 
is the class name of the instance and so is determined when the instance is 
created. The context of tr()/trUtf8() calls shouldn't make any difference.

Phil

> 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




More information about the PyQt mailing list