How to insert accented characters in Text Inputs in PyQt5?

0

My text entries in PyQt5 (QLineEdit, QPlainTextEdit, Dialogs, ...) do not accept accented characters typed on the keyboard. I can only insert them if I type them in another editor and call Crtl + C, Crtl + V, or by commands in the source code. This happens to text widgets, whether they were created locally, dynamically, or imported from Qt Designer. I believe the problem is in PyQt, because when I test it in Qt Designer, it works perfectly. I use Ubuntu Studio. Does anyone know how to solve it?

    
asked by anonymous 29.03.2017 / 19:37

1 answer

0

I managed to resolve. At least for me, it works. I've done the following:

From QLineEdit, QPlainTextEdit and QTextEdit, I have created three new widgets, respectively QLineEdit_Ac, QPlainTextEdit_Ac, and QTextEdit_Ac.

If you are interested, to use these widgets just add the acentos.py file and import them. If you decide to test the code, leave your feedback in the comments it helps. You can also help develop them.

accents.py

# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QTextEdit, QLineEdit, QPlainTextEdit

class acentuacao():
    """
    KEYS : código das teclas "text_widget.before_key" que acionarão a substituição: (til, acento circunflexo, acento agudo, crase, trema)
    CA : cada CA[i] corresponde ao seu KEY[i] --> devem estar na mesma ordem
    cada um dos itens de cada CA[i] é representado como
    ('~', ('a', 'e', 'i, ...),('ã', 'ẽ', 'ĩ',...)) onde:
        '~' : caracter que deve ser impresso, caso o seguinte não esteja na relação, 
        ('a', 'e', 'i, ...) : caracteres que serão substituidos
        ('ã', 'ẽ', 'ĩ',...) : caracteres que pelos quais, respectivamente, aqueles serão substituidos
    """
    KEYS = [16781907, 16781906, 16781905, 16781904, 16781911]
    CA = [
         ('~', ('a', 'e', 'i', 'o', 'u', 'n', 'A', 'E', 'I', 'O', 'U', 'N'),
               ('ã', 'ẽ', 'ĩ', 'õ', 'ũ', 'ñ', 'Ã', 'Ẽ', 'Ĩ', 'Õ', 'Ũ', 'Ñ')),
         ('^', ('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'),
               ('â', 'ê', 'î', 'ô', 'û', 'Â', 'Ê', 'Î', 'Ô', 'Û')),
         ('',  ('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'),
               ('á', 'é', 'í', 'ó', 'ú', 'Á', 'É', 'Í', 'Ó', 'Ú')),
         (''', ('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'),
               ('à', 'è', 'ì', 'ò', 'ù', 'À', 'È', 'Ì', 'Ò', 'Ù')),
         ('',  ('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'),
               ('ä', 'ë', 'ï', 'ö', 'ü', 'Ä', 'Ë', 'Ï', 'Ö', 'Ü')) ]

    def check_acentuacao(text_widget, event):
        Result = None
        if text_widget.before_key in acentuacao.KEYS:
            n = acentuacao.KEYS.index(text_widget.before_key)
            ca = acentuacao.CA[n]
            r = ca[0]                               # inicializando, apenas com o sinal
            if str(event.text()) in ca[1]:          # se event.text() é um dos caraceres substituíveis,
                i = ca[1].index(str(event.text()))
                r = ca[2][i]                        # r assume o valor deste, com seu respectivo acento
            Result = r

        if not event.key() == 16777248:    # O Shift é uma tecla problemática, porque muda o codigo do before_key
            text_widget.before_key = event.key()

        """ Para visualizar o valor de cada tecla (KEY) pessionada, descomente a linha abaixo """
        #print('KEY =',  event.key())

        return Result

#***************************************************************************************************
#************* QLineEdit  ******************************************************************************
class QLineEdit_Ac(QLineEdit):
   def __init__(self, parent=None):
      super(QLineEdit_Ac, self).__init__(parent)
      QLineEdit_Ac.before_key = None

   def keyPressEvent(self, e):
       Rt = acentuacao.check_acentuacao(QLineEdit_Ac, e)
       if Rt != None:
           self.insert(Rt)
       else:
           super(QLineEdit_Ac, self).keyPressEvent(e)

#***********  QTextEdit_Ac ************************************************************************
class QPlainTextEdit_Ac(QPlainTextEdit):
    def __init__(self, parent=None):
        super(QPlainTextEdit_Ac, self).__init__(parent)
        QPlainTextEdit_Ac.before_key = None

    def keyPressEvent(self, e):
        Rt = acentuacao.check_acentuacao(QTextEdit_Ac, e)
        if Rt != None:
            self.insertPlainText(Rt)
        else:
            super(QPlainTextEdit_Ac, self).keyPressEvent(e)

#***********  QTextEdit_Ac ************************************************************************
class QTextEdit_Ac(QTextEdit):
    def __init__(self, parent=None):
        super(QTextEdit_Ac, self).__init__(parent)
        QTextEdit.before_key = None

    def keyPressEvent(self, e):
        Rt = acentuacao.check_acentuacao(QTextEdit_Ac, e)
        if Rt != None:
            self.insertPlainText(Rt)
        else:
            super(QTextEdit_Ac, self).keyPressEvent(e)

test.py

# -*- coding: utf-8 -*-
""" Serve para testar, e exemplo de uso dos widgets 
    QLineEdit_Ac, QPlainTextEdit_Ac e QTextEdit_Ac
"""
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from acentos import *

class Exemplo(QMainWindow):
    def __init__(self):
        super().__init__()
        # Criando os Widgets de entrada de texto acentuado
        unica_linha = QLineEdit_Ac()
        multi_linhas = QPlainTextEdit_Ac()
        rich_text = QTextEdit_Ac()
        # ---A partir daqui, nenhuma novidade...
        self.setWindowTitle('Teste de acentuação')
        frame = QFrame()
        self.setCentralWidget(frame)

        layout = QVBoxLayout()
        layout.addWidget(QLabel('Única Linha (QLineEdit_Ac)'))
        layout.addWidget(unica_linha)
        layout.addWidget(QLabel('Várias linhas (QPlainTextEdit_Ac)'))
        layout.addWidget(multi_linhas)
        layout.addWidget(QLabel('Editor Rich Text (QTextEdit_Ac)'))
        rich_text.insertHtml("<b><big>Até</big></b> isso <small>é</small> "
                             "<font color = blue><i> possível!</i></font>")
        layout.addWidget(rich_text)
        frame.setLayout(layout)
        self.statusBar()

        # Menus
        exitAct = QAction(QIcon('exit.png'), '&Sair', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Vazar beco afora...')
        exitAct.triggered.connect(qApp.quit)

        aboutAct = QAction("Sobre o App...", self)
        aboutAct.setStatusTip('Sobre este app...')

        aboutQtAct = QAction("Sobre Qt...", self)
        aboutQtAct.setStatusTip('Sobre a biblioteca Qt em uso...')

        aboutAct.triggered.connect(self.about)
        aboutQtAct.triggered.connect(QApplication.instance().aboutQt)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&Arquivo')
        fileMenu.addAction(exitAct)

        helpMenu = self.menuBar().addMenu("Sobre...")
        helpMenu.addAction(aboutAct)
        helpMenu.addAction(aboutQtAct)


        # Centrar o App na tela
        App_Width = 500
        App_Height = 400

        screen_resolution = app.desktop().screenGeometry()

        posx = int((screen_resolution.width() - App_Width) / 2 )
        posy = int((screen_resolution.height() - App_Height) / 2 )
        self.setGeometry(posx, posy, App_Width, App_Height)

        self.show()

    def about(self):
        QMessageBox.about(self, "Sobre este app",
            "Esta é uma demonstração do uso do QLineEdit_Ac e "
            "QTextEdit_Ac, widgets estes, que, respectivamente possibilitam o "
            "uso da acentuação no QLineEdit e QTextEdit. "
            "Caso encontre algum bug, por favor, comunique.\n"
            "David Jesse")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Exemplo()
    sys.exit(app.exec_())
    
30.03.2017 / 01:36