IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

QTextEdit et limitation de saisie / validation d'entrées


Sujet :

PyQt Python

  1. #1
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Points : 91
    Points
    91
    Par défaut QTextEdit et limitation de saisie / validation d'entrées
    Bonjour, je souhaite utiliser un QtextEdit dont je limiterai la saisie au clavier aux lettres atgc (pour l'ADN, je suis biologiste...). J'ai vu qu'il n'existe rien de semblable au Qvalidator de QlineEdit pour QtextEdit.

    La seule info que j'ai trouvée est ce post mais la solution ne me plait pas car en désactivant l'édition du QtextEdit, je perds les bindings de navigation avec les touches....

    Dans le processus de traitement des événements clavier par défaut du Qtextedit, n 'y a t il pas une méthode genre "insert..." qui soit appellée lors d'un evenement clavier que je puisse surcharger pour "nettoyer" tout caractère différent de 'a', 't', 'g' ou 'c' histoire de "limiter la saisie" de mon QtextEdit?

    Une idée pour m'aider?

  2. #2
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Essayes de regarder du côté des keyEvent.

    Ou bien regardes du côté de....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.connect(self.textEdit, QtCore.SIGNAL("textChanged()"), self.chgtTexte)
    Ensuite la méthode chgtTexte peut nettoyer tous les caractères qui te gênent.

    Si tu arrives à faire quelque chose avec la 1ère idée, je suis preneur.

  3. #3
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Points : 91
    Points
    91
    Par défaut
    Salut, pour ce qui est de la deuxième solution avec nettoyage de code, j'ai tenté avec le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #!/usr/bin/python
     
    # simple.py
    import sys, string
    from PyQt4 import QtGui, QtCore
     
    app = QtGui.QApplication(sys.argv)
     
    widget = QtGui.QWidget()
    widget.resize(250, 150)
    widget.setWindowTitle('simple')
     
    txt = QtGui.QTextEdit(widget)
    txt.setText("ccaatt")
    def cl():
        print "clean=========="
        temp = txt.toPlainText()
        temp = temp.replace("a", "")
        txt.setText(temp)
    widget.connect(txt, QtCore.SIGNAL('textChanged()'), cl)
    widget.show()
    sys.exit(app.exec_())
    mais j'obtiens le message d'erreur suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    clean==========
    ...
    ...
    clean==========
    clean==========
    RuntimeError: maximum recursion depth exceeded
    Je ne sais pas d'où viennent ces itérations sachant que je ne fais la modification de texte qu'une fois et que je n'ai changé que deux charactères "a".

    C'est pour cela que je cherchais une autre solution.

  4. #4
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    L'erreur est normale...
    Dans...
    ..., tu changes le texte, du coup PyQt, très logiquement, va appeler ta fonction car tu as...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    widget.connect(txt, QtCore.SIGNAL('textChanged()'), cl)
    ..., et on rentre dans une boucle infinie. Du coup, je ne sais pas si cela est la bonne méthode...

    As-tu regardé tu côté de KeyEvent qui ne présentera pas ce défaut ?
    Je vais essayer de mon côté de voir comment faire cela même si de prime abord la chose ne semble pas simple. Il faut à mon avis créer une classe textEdit particulière (par surclassage) pour y récupérer les évènements (mais comme d'habitude il n'est pas évident de trouver des exemples basiques).

    Si j'arrive à quelque chose, je le posterais ici.

  5. #5
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Points : 91
    Points
    91
    Par défaut
    Salut, je pensais que le signal textchanged fonctionnait par différence avec le texte qui était présent avant. Mais si, faire un setText(), active le signal même si le nouveau contenu est identique à l'ancien contenu, je comprends que la boucle soit infinie. je pourrais casser la boucle infinie en ne faisant le settext que si le texte nettoyé est différent du text d'avant nettoyage, mais cela ne me parait pas très propre comme codage....

    EDIT : j'ai tenté de casser la boucle, mais cela ne semble par marcher.... car setText envoie le signal avant de changer le texte!!!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #!/usr/bin/python
     
    # simple.py
    import sys, string
    from PyQt4 import QtGui, QtCore
     
    app = QtGui.QApplication(sys.argv)
     
    widget = QtGui.QWidget()
    widget.resize(250, 150)
    widget.setWindowTitle('simple')
     
    txt = QtGui.QTextEdit(widget)
    txt.setText("ccaatt")
    def cl():
        print "clean=========="
        temp = txt.toPlainText()
        temp2 = txt.toPlainText()
        temp = temp.replace("a", "")
        print temp, temp2, txt.toPlainText()
        if temp != temp2:
            txt.setText(temp2)
    widget.connect(txt, QtCore.SIGNAL('textChanged()'), cl)
    widget.show()
    sys.exit(app.exec_())
    Question : peut on déconnecter l'émission du signal textchanged de la méthode setText? cela devrait régler le problème de la boucle infinie?

  6. #6
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Salut,
    voilà une solution possible à partir de ton idée. C'est pas propre du tout mais bon peut-être que cela te conviendra.
    J'ai peu de temps libre en ce moment mais je vais tacher de trouver une solution via les "event" qui elle sera forcément propre c'est sûr. Faut juste que je trouve une heure ou deux pour me pencher sur la question (c'est de toute façon sur la liste de actions de PyQt que je veux apprendre à gérer).

    Voici les deux codes (à mettre dans le même dossier) permettant de répondre à ton problème.

    Code interface fait via QT Designer. Nom ==> keyEventForm.py
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    # -*- coding: utf-8 -*-
     
    # Form implementation generated from reading ui file 'C:\Documents and Settings\Christophe\Mes documents\2,pyBaNaMa\DebuterAvecPythonEtPyQT\CodesProjets\77-KEyEventAndCo\keyEventForm.ui     '
    #
    # Created: Sat Feb 14 15:38:08 2009
    #      by: PyQt4 UI code generator 4.4.4
    #
    # WARNING! All changes made in this file will be lost!
     
    from PyQt4 import QtCore, QtGui
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(395, 292)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
            self.verticalLayout.setObjectName("verticalLayout")
            self.textEdit = QtGui.QTextEdit(self.centralwidget)
            self.textEdit.setObjectName("textEdit")
            self.verticalLayout.addWidget(self.textEdit)
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtGui.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 395, 21))
            self.menubar.setObjectName("menubar")
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtGui.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
     
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
     
        def retranslateUi(self, MainWindow):
            MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
     
     
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())
    Code de l'application.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    # -*- coding: utf-8 -*-
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    from keyEventForm import Ui_MainWindow
     
     
    class keyEvent_Plus(QtGui.QMainWindow, Ui_MainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            Ui_MainWindow.__init__(self)
            self.setupUi(self)
    #        self.textEdit.setText('tgca')
            self.connect(self.textEdit, QtCore.SIGNAL("textChanged()"), self.chgtTexte)
     
        def chgtTexte(self):
            print "clean=========="
            if 'a' in self.textEdit.toPlainText():
                temp = self.textEdit.toPlainText()
                temp = temp.replace("a", "")
                print temp, self.textEdit.toPlainText()
     
                self.textEdit.setText(temp)
    # Pour aller à la fin du texte.
                self.textEdit.moveCursor(QtGui.QTextCursor.End)
     
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        test = keyEvent_Plus()
        test.show()
        sys.exit(app.exec_())

  7. #7
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Points : 91
    Points
    91
    Par défaut
    En effet, ca marche, merci, j'ai plus qu'à adapter pour que tout soit nettoyé excepté les atgc...

    Mais ce que je ne comprends pas, c'est où est la différence avec mon code? Je ne comprends pas ce qui fait que ton code fonctionne et que le mien pose problème.

    Question annexe, connais tu un tutorial sur les qkeyevent? Je souhaite comprendre comment "faire un binding de keypress_A" sur un widget quelconque. Sous Tk, facile, sous PyQt, je ne comprends pas et je ne trouve rien pour m'expliquer.

  8. #8
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Voici une méthode avec la gestion du clavier.

    Code de l'interface graphique keyEventForm_Plus. On a ajouté une nouvelle classe textPlus.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    # -*- coding: utf-8 -*-
     
    from PyQt4 import QtCore, QtGui
     
    class textPlus(QtGui.QTextEdit):
        def keyPressEvent(self, event):
            if event.key() in [ord('G'), ord('C'), ord('T'), ord('A')]:
    # On a bien l'une des lettres attendues.
                self.setText(self.toPlainText() + chr(event.key()))
                self.moveCursor(QtGui.QTextCursor.End)
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(395, 292)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
            self.verticalLayout.setObjectName("verticalLayout")
            self.textEdit = textPlus()
            self.textEdit.setObjectName("textEdit")
            self.verticalLayout.addWidget(self.textEdit)
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtGui.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 395, 21))
            self.menubar.setObjectName("menubar")
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtGui.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
     
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
     
        def retranslateUi(self, MainWindow):
            MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
     
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())
    L'application devient toute simple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # -*- coding: utf-8 -*-
     
    import sys
    from PyQt4 import QtCore, QtGui
     
    from keyEventForm_Plus import Ui_MainWindow
     
     
    class keyEvent_Plus(QtGui.QMainWindow, Ui_MainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            Ui_MainWindow.__init__(self)
            self.setupUi(self)
     
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        test = keyEvent_Plus()
        test.show()
        sys.exit(app.exec_())

  9. #9
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Points : 91
    Points
    91
    Par défaut
    Merci pour la méthode avec gestion du clavier. Je vais regarder cela en détails.

    Sinon j'ai retouché mon code et ca marche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #!/usr/bin/python
     
    # simple.py
    import sys, string
    from PyQt4 import QtGui, QtCore
     
    app = QtGui.QApplication(sys.argv)
     
    widget = QtGui.QWidget()
    widget.resize(250, 150)
    widget.setWindowTitle('simple')
     
    txt = QtGui.QTextEdit(widget)
    txt.setText("ccaahtt")
     
    def cl():
        print "clean=========="
        temp = str(txt.toPlainText())
        temp2 = []
        mod = False
        for i in temp:
    	if not i in "atgcnuATGCNU":
    	    print i
    	    mod = True
    	else:
    	    temp2.append(i)
        if mod == True:
    	txt.setText("".join(temp2))
    widget.connect(txt, QtCore.SIGNAL('textChanged()'), cl)
    widget.show()
    sys.exit(app.exec_())

  10. #10
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par atalon1 Voir le message
    En effet, ca marche, merci, j'ai plus qu'à adapter pour que tout soit nettoyé excepté les atgc...
    C'est fait.

    Citation Envoyé par atalon1 Voir le message
    Question annexe, connais tu un tutorial sur les qkeyevent? Je souhaite comprendre comment "faire un binding de keypress_A" sur un widget quelconque. Sous Tk, facile, sous PyQt, je ne comprends pas et je ne trouve rien pour m'expliquer.
    Trouver un tutoriel sur PyQt n'est pas aisé, je ne connais rien de satisfaisant. De mon côté, j'ai un squelette de tuto. mais faute de temps je ne peux le publier (sûrement cela sera fait à la fin de cet été).
    Sinon regardes un peu le code que je viens de poster. Pour comprendre PyQt, il faut que tu saches manipuler le surclassage. Une fois cela compris, tout est relativement simple.

    Quand je tape...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class textPlus(QtGui.QTextEdit):
    ..., je surclasse la classe QTextEdit standard pour en faire une qui me convienne.

    Ensuite,...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        def keyPressEvent(self, event):
            ...
    ... me permet de redéfinir la méthode keyPressEvent (voir cette page pour avoir des infos plus ou moins claires sur les classes de PyQt). Il ne reste plus qu'à faire le traitement souhaité.

    Si je peux te donner un conseil. Fais toujours des interfaces via QtDesigner. Ensuite modifies éventuellement le code par surclassage comme je l'ai fait. Pour finir, importe ce code de l'interface dans celui de ton application (ainsi dans ce dernier code, tu ne feras que du traitement de données, ceci rend les choses très claires). On sépare ainsi la forme avec ses comportements du reste de l'application. Un paradigme très efficace que de séparer le fond de la forme.

    En espérant t'avoir aidé un peu.

    PS : pour être réellement opérationnel, il faudrait que mon code puisse permettre de taper où on veut le nouveau caractère car là il faut le faire tout à la suite. A creuser...

  11. #11
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par atalon1 Voir le message
    Merci pour la méthode avec gestion du clavier. Je vais regarder cela en détails.
    Si tu as des questions, n'hésites pas.

    Citation Envoyé par atalon1 Voir le message
    Sinon j'ai retouché mon code et ca marche.
    Effectivement. Ta méthode est meilleure que la mienne car la place du curseur peut être quelconque. Ceci étant dit, ta question ma permis de voir un peu mieux comment gérer le clavier au sein d'un QTextEdit.

  12. #12
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Points : 91
    Points
    91
    Par défaut
    Tout d'abord, merci pour tout!!!!

    Je me suis mis à PyQt que très récemment et j'avoue que je n'ai pas encore cerné toute la logique, d'où ma question sur les bindings...

    Mais comme tu le conseilles, et comme indiqué dans le seul tutoriel que j'ai trouvé (PyQT et Eric 3), je fais l'interface dans qtdesigner et je dérive la classe... Sauf dans mes exemple, pour simplifier le code...

    Effectivement. Ta méthode est meilleure que la mienne car la place du curseur peut être quelconque.
    Meilleure, je ne sais pas, mais pour ce qui est du curseur, enregistrer la position du curseur avant d'insérer le charactère devrait suffire, ...j'ai fais cela sous Tk.

    Encore merci pour l'aide précieuse !!!

  13. #13
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut Une méthode avec les evnts
    Finalement voici ce qu'il faut faire pour respecter la position du curseur en utilisant keyPressEvent.
    L'avantage de cette méthode est d'éviter de parcourir tout le texte ce qui peut ralentir l'exécution du code (bien que je doute qu'en pratique cela soit perceptible dans le cadre de ton application).

    Code fonctionnelle de l'interface graphique keyEventForm_Plus.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    # -*- coding: utf-8 -*-
     
    from PyQt4 import QtCore, QtGui
     
    class textPlus(QtGui.QTextEdit):
        def keyPressEvent(self, event):
    # On redéfinie la méthode keyPressEvent pour
    # n'accepter que certaines touches du clavier.
     
    #  Cas des touches attendues.
            if event.key() in (QtCore.Qt.Key_G, QtCore.Qt.Key_C, QtCore.Qt.Key_T, QtCore.Qt.Key_A):
                curseur=self.textCursor()
                curseur.insertText(chr(event.key()))
     
    # Cas des déplacements à l'aide du clavier.
            elif event.key() == QtCore.Qt.Key_Left:
                self.moveCursor(QtGui.QTextCursor.PreviousCharacter)
            elif event.key() == QtCore.Qt.Key_Right:
                self.moveCursor(QtGui.QTextCursor.NextCharacter)
            elif event.key() == QtCore.Qt.Key_End:
                self.moveCursor(QtGui.QTextCursor.End)
            elif event.key() == QtCore.Qt.Key_Backtab:
                self.moveCursor(QtGui.QTextCursor.Start)
     
    # Deux trucs trouvés dans le livre « Rapid GUI Programming
    # with Python and Qt » de Mark SUMMERFIELD.
     
    # TRUC 1 : Gérér une séquence comme CTRL + TAB.
    #        elif event.key() == QtCore.Qt.Key_Tab:
    #            if event.modifiers() and QtCore.Qt.ControlModifier:
    #                print 'CTRL + TAB'
    # TRUC 2 : Pour accepter toutes les autres actions.
    #        else:
    #            QtGui.QTextEdit.keyPressEvent(self, event)
     
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(395, 292)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
            self.verticalLayout.setObjectName("verticalLayout")
            self.textEdit = textPlus()
            self.textEdit.setObjectName("textEdit")
            self.verticalLayout.addWidget(self.textEdit)
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtGui.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 395, 21))
            self.menubar.setObjectName("menubar")
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtGui.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
     
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
     
        def retranslateUi(self, MainWindow):
            MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
     
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())

  14. #14
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par atalon1 Voir le message
    Mais comme tu le conseilles, et comme indiqué dans le seul tutoriel que j'ai trouvé (PyQT et Eric 3), je fais l'interface dans qtdesigner et je dérive la classe... Sauf dans mes exemple, pour simplifier le code...
    Sur un projet petit ceci n'est pas nécessaire. Maintenant si tu te lances dans une application avec une interface graphique riche, il faut faire cela car il est plus aisée et surtout rapide de travailler avec QtDesigner pour placer les éléments, définir des menus...
    En cas de surclassage comme ci-dessus, j'ai pris l'habitude d'utiliser un fichier à part que j'importe. Cela fait peu de lignes à changer en cas de modifications de l'interface via QtDesigner.

    Encore une fois merci car indirectement ta question m'a fait me pencher un peu sur le QTexteEdit, même si je n'avais pas vraiment le temps. Curiosité quand tu nous tiens...

  15. #15
    Membre régulier
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Points : 91
    Points
    91
    Par défaut
    Voilà, pour aider tous ceux qui comme moi ont besoin de filtrer la saisie d'un QtextEdit, et bien sur grâce à toutes les aides et propositions apportées dans et hors de cette discussion (merci rambc ), je vous propose le code suivant :

    [EDIT] le code est un peu plus propre maintenant..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    from PyQt4 import QtCore, QtGui
     
    class QTextEditATGCNU(QtGui.QTextEdit):
        """QTextEdit for DNA/RNA sequences.
        
        Accepts only ATGCNU key events, navigation shortcuts are reimplemented, cut, copy and paste functions also with cleaning of the clipboard string content before pasting.
        """
     
        def cleanNucleic(self,  seqToClean):
            """Removes non GATCNU chars from the string."""
            cleaned = []
            for i in str(seqToClean):
                if str(i) in "atgcnuATGCNU":
                    cleaned.append(i)
            return "".join(cleaned)
     
        def paste(self):
            """Pastes clipboard content after cleaning."""
            clipboard = QtGui.QApplication.clipboard()
            self.insertPlainText(self.cleanNucleic(clipboard.text()))
     
        def keyPressEvent(self, event):
            """Redefines keyPress events"""
     
            # ShortCuts with CONTROL key Modifier
            if event.modifiers() == QtCore.Qt.ControlModifier:
                if event.key() == QtCore.Qt.Key_A:
                    self.selectAll()
                if event.key() == QtCore.Qt.Key_X:
                    self.cut()
                if event.key() == QtCore.Qt.Key_C:
                    self.copy()
                if event.key() == QtCore.Qt.Key_V:
                    self.paste()
     
            # Without modifier or with SHIFT
            else:
                # Sets navigation or selection mode according to SHIFT key usage
                modShift = QtGui.QTextCursor.MoveAnchor
                if event.modifiers() == QtCore.Qt.ShiftModifier:
                    modShift = QtGui.QTextCursor.KeepAnchor
                # Accepted key inputs
                if event.key() in (QtCore.Qt.Key_G, QtCore.Qt.Key_C, QtCore.Qt.Key_T, QtCore.Qt.Key_A, QtCore.Qt.Key_N, QtCore.Qt.Key_U):
                    QtGui.QTextEdit.keyPressEvent(self, event)
                # Navigation or selection with keys
                elif event.key() == QtCore.Qt.Key_Up:
                    self.moveCursor(QtGui.QTextCursor.Up,  modShift)
                elif event.key() == QtCore.Qt.Key_Down:
                    self.moveCursor(QtGui.QTextCursor.Down,  modShift)
                elif event.key() == QtCore.Qt.Key_Left:
                    self.moveCursor(QtGui.QTextCursor.Left,  modShift)
                elif event.key() == QtCore.Qt.Key_Right:
                    self.moveCursor(QtGui.QTextCursor.Right,  modShift)
                elif event.key() == QtCore.Qt.Key_Home:
                    self.moveCursor(QtGui.QTextCursor.Start,  modShift)
                elif event.key() == QtCore.Qt.Key_End:
                    self.moveCursor(QtGui.QTextCursor.End,  modShift)
    Ce QTextEdit n'accepte que les lettres A, T, G, C, N ou U. La navigation et la sélection avec les flèches est réimplémentée et les raccourcis couper, copier et coller fonctionnent également. Pour la fonction coller, le contenu du presse papier est "nettoyé" avant d'être collé pour n'accepter que les lettres A, T, G, C, N ou U.

    Voilà, j'espère que cela en aidera d'autres...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WD9] Validation d'un champ de saisie avec touche entrée
    Par EpOnYmE187 dans le forum WinDev
    Réponses: 11
    Dernier message: 13/01/2006, 15h28
  2. [SQL] Limiter la saisie dans une table
    Par dolphi dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 16/09/2005, 11h43
  3. Limiter la saisie dans un élément texte
    Par manou.K dans le forum Oracle
    Réponses: 2
    Dernier message: 28/07/2005, 11h41
  4. [JFormattedTextField] limiter la saisie
    Par anitshka dans le forum Composants
    Réponses: 6
    Dernier message: 23/05/2005, 14h23
  5. limiter la saisie dans un edit à des réels!!!
    Par shout dans le forum Windows
    Réponses: 10
    Dernier message: 21/06/2004, 16h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo