2010-11-10 29 views
6

¿Es posible usar Tkinter para representar interfaces de usuario para lenguajes RTL como árabe o hebreo? Intenté buscar en Google en "tkinter rtl" y los resultados de búsqueda fueron decepcionantes. El Tk wiki indica que no hay soporte bidi en este momento.Python/Tkinter: ¿Cómo usar Tkinter para RTL (de derecha a izquierda) idiomas como árabe/hebreo?

¿Alguien está desarrollando aplicaciones de Tkinter para entornos en árabe o hebreo?

+0

un poco más en esto en: http://wiki.tcl.tk/699 –

+0

Desde 2011, tk y por lo tanto tkinter y IDLE soportan bidi en hebreo y árabe en Windows usando soporte de Windows. https://wiki.tcl.tk/3158. Acabo de agregar algunos de cada uno a la muestra de selección de fuentes en IDLE para que la gente pueda ver qué funciona o no en su sistema particular. –

Respuesta

3

Me doy cuenta de que esta es una vieja pregunta, pero ayer comencé a trabajar con Tkinter para desarrollar una aplicación hebrea en Python. De derecha a izquierda (bidi) no está disponible como parte del marco, pero después de un poco de búsqueda en Google y un poco de investigación, logré falsificarlo de manera convincente mediante combinaciones de teclas y reposicionando el cursor por la fuerza. El widget My Entry conserva la justificación, de modo que el texto en hebreo se encuentra más o menos en la misma posición que un inglés en el mismo cuadro, pero este enfoque podría modificarse fácilmente para un cuadro justificado a la derecha. (O bien, la justificación correcta podría simplificar esto). No obstante, esto es lo que hice.

Esencialmente, lo que está haciendo aquí es aplicar manualmente la posición del cursor mediante devoluciones de llamada, códigos de caracteres y constantes de índice. Además, debes tener en cuenta las teclas de flecha (las mías se comportan como moviéndose en la dirección que señalan. Siempre he odiado cómo RTL generalmente invierte las flechas. Sin embargo, esto se cambia fácilmente si prefieres lo contrario.) Retroceso y Del, también, tiene que causar algún reposicionamiento manual. Por supuesto, también, si realiza un seguimiento del cursor manualmente, debe actualizar su variable de seguimiento en caso de que el usuario la vuelva a colocar usando el mouse. A continuación está mi código, con la excepción de que el uso de un global aquí tiene la intención de eliminar un ápice de complejidad de la explicación.

   # Here, the necessary bindings. We're going to 
      # have to make modifications on key press, release, 
      # and on a completed mouse click. 
      entryWidget.bind("<KeyPress>", rtlPress) 
      entryWidget.bind("<KeyRelease>", rtlRelease) 
      entryWidget.bind("<ButtonRelease>", rtlMouse) 

A continuación, las tres funciones de devolución de llamada, que hacen todo nuestro cursor de seguimiento y reubicación.

#With the following functions, keep in mind that we only want the cursor to move RIGHT 
#(increase in index) in response to a right arrow press or a DEL. Essentially, we are 
#compensating for any movement but these explicit conditions. Since the indexing of the 
#cursor position is LTR, holding it in its current position 
#while we append more text is 
#tantamount to moving it right. 

#On key release, if an arrow key has been invoked, we update our tracking variable to 
#reflect the new cursor position. If any other key was pressed, we snap the cursor back 
#to where it was prior to the keypress to prevent it from moving right and cause the 
#next letter to be appended on the left side of the previous letter. 

def rtlRelease(event): 
     global hebCursorPos 
     if event.keycode==114 or event.keycode==113: 
       hebCursorPos=event.widget.index(INSERT) 
     else: 
       event.widget.icursor(hebCursorPos) 
     print(str(event.keycode)+" "+str(hebCursorPos)) 

#On keypress, we must compensate for the natural LTR behavior of backspace(22) and 
#del(119) 

def rtlPress(event): 
     global hebCursorPos 
     #In LTR text entry, a backspace naturally removes the character to the left of 
     #the cursor. 
     if event.keycode==22: 
       length = len(event.widget.get()) 
       #In RTL, the right edge is the beginning of the string, so backspace 
       #should do nothing. 
       #If we're at the right edge of the string, we insert a meaningless 
       #character to be deleted so that it appears to the user as if we have 
       #done nothing. 
    if hebCursorPos==length: 
         event.widget.insert(hebCursorPos, " ") 
       #In order to cause the backspace to delete the character to the right 
       #rather than the left of the cursor from the user's perspective, we step 
       #the cursor forward one. This will cause the backspace to delete the 
       #character to the left of the new cursor position, which will be the 
       #character that was to the right of the cursor from the user's 
       #perspective. If we were at the right end of the line, we insert a space 
       #and delete it milliseconds later. We do not need to update the cursor's 
       #position, in the tracking variable, because after the character is 
       #deleted, it is back at the index from which it started, counting index 
       #from an LTR perspective. 
       event.widget.icursor(hebCursorPos+1) 
     else: 
       #Del is more of the same. It deletes the character to the right of the 
       #cursor, but we want it to delete the character to the right. 
       if event.keycode==119: 
       #If we're at the left edge of the string, insert a meaningless character 
       #for the del to delete, so that from the user's perspective it does 
       #nothing. 
         if hebCursorPos==0: 
           event.widget.insert(hebCursorPos, " ") 
         #Otherwise, we will be stepping the cursor one to the left, so 
         #that when it deletes the character to its new right, it will be 
         #deleting the character from what the user thinks is its left. 
         #Because we are deleting a character from the left of the cursor 
         #from the user's perspective, there will be fewer characters to 
         #the left of the cursor once the operation is complete. As 
         #cursor positioning is tracked as an LTR index, we must update 
         #our tracking variable. 
         else: 
           hebCursorPos-=1 
       #Now, we snap our cursor to the position of our tracking variable. 
       #Either we are preventing it from drifting right due to overlapping 
       #keypresses, or we are repositioning it to maintain the correct index 
       #after a del. 
       event.widget.icursor(hebCursorPos) 

#Simply put, if the user repositions the cursor with the mouse, track it. 
def rtlMouse(event): 
     global hebCursorPos 
     hebCursorPos=event.widget.index(INSERT) 

Hope this helps! Dado que se realiza mediante el movimiento forzado del cursor, hay una ligera fluctuación visual del cursor durante el tipeo, pero el orden del texto parece ser correcto, y el cursor parece indicar siempre la posición correcta cuando el usuario no está presionando la tecla a la mitad. Sin embargo, ¡no estoy haciendo ningún reclamo por la perfección del código!

+0

Este es un hack horrible, y solo aborda una fracción de los problemas presentados por la traducción de texto árabe/hebreo. – dietr

0

esto quizás no resuelva el problema completo tampoco, pero puede resolver el problema de la visualización que veo el problema principal.

básicamente se necesitan dos cosas para revertir orden de los caracteres y dejar que se unen i utilizado este reshaper, funcionó muy bien con palabras sencillas y sin diacríticos الحركات pero todavía buggy en algunos casos.

Cuestiones relacionadas