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

Qt Discussion :

Intégrer un éditeur de code dans une application


Sujet :

Qt

  1. #1
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut Intégrer un éditeur de code dans une application
    Bonjour,
    Je travaille sur une application permettant la création de sources (Pascal, C, C++..) dont certaines parties sont automatisées. A une certaine étape cependant l'utilisateur doit saisir du code. Il faudrait donc idéalement lui fournir toutes les fonctionnalités d'un IDE pour simplifier la saisie du code, en pratique selon le temps nécessaire, ça sera bien sûr quelque chose de beaucoup plus réduit.

    On m'avait parlé de QScintilla qui intégrait déjà pas mal de ces fonctionnalités, mais manque de bol, la licence GPL est incompatible avec la licence BSD de l'application sur laquelle je travaille.
    J'ai vu que Qt propose nativement QPlainTextEdit qui pourrait être un bon début (coloration syntaxique, gestion du copier/coller), mais qui semble plus adapté à la saisie de document que de code, du fait qu'il fonctionne par paragraphe [i.e. blocs séparés par des sauts de ligne] et que du code sources est plutôt beaucoup de lignes contenant peu de mots. Malgré ça, l'auto-indentation, l'auto-complétion seraient manquantes. Je ne rend pas trop compte à quel point c'est compliqué à mettre en place.

    Donc, est-ce quelqu'un connaitrait des choses externes dans le genre de QScintilla (mais sous licence LGPL/BSD) ?
    Et, est-ce que QPlainTextEdit reste adapté pour saisir du code, ou vaut-il mieux utiliser QTextEdit ?

    Merci d'avance

  2. #2
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 169
    Points : 496
    Points
    496
    Par défaut
    Salut,
    QSyntaxHighlighter permet de faire ça.
    Voici un exemple http://qt.developpez.com/doc/latest/...ghlighter.html .

  3. #3
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Merci oui, ça j'avais déjà vu ma question n'est pas exactement là. Car dans l'idéal je voudrais beaucoup plus de fonctionnalités qu'une simple coloration syntaxique (indentation auto, auto-complétion...).

  4. #4
    Rédacteur

    Avatar de johnlamericain
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    3 742
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 3 742
    Points : 8 140
    Points
    8 140
    Par défaut
    Citation Envoyé par kmedghaith Voir le message
    Salut,
    QSyntaxHighlighter permet de faire ça.
    Voici un exemple http://qt.developpez.com/doc/latest/...ghlighter.html .
    Je pense que cette classe sert uniquement à la coloration syntaxique ce qui est un bon début mais pas suffisant pour les besoins du projet.

    Tu peux regarder plus en détail la classe QTextDocument (http://qt.developpez.com/doc/latest/qtextdocument.html) et combiner les 2 classes dans un QTextEdit.

  5. #5
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 169
    Points : 496
    Points
    496
    Par défaut
    et pour la completition du code, tu peux regarder cet exemple http://qt.developpez.com/doc/latest/...completer.html

  6. #6
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonsoir,

    Ayant travaillé sur un IDE, j'ai réalisé un éditeur de texte tel que tu sembles avoir besoin. Il s'agit d'une classe héritant de QPlainTextEdit. Pour l'auto-complétion, elle utilise la classe QCompleter, pour la coloration, QSyntaxHighlighter, pour la numérotation de ligne, un QWidget avec un paintEvent, et pour l'indentation automatique, il s'agit d'une indentation dans le keyPressEvent à partir du textCursor. Les bulles d'aide informant sur les prototypes sont gérées à la main, mais pas par QToolTip::showText() qui est très lent pour ce genre de travail.
    Globalement, c'est comme on te l'a dit, mais si tu as des questions sur l'implémentation, n'hésites pas !

    Espérant avoir éclairé ta lanterne,
    Amnell.

  7. #7
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Merci de vos réponses, j'ai tardé à répondre car j'ai dû faire d'autres tâches entre temps. Je me penche maintenant sur le fameux éditeur, j'ai intégré la coloration syntaxique sans problème.

    J'ai une petite question, pour fixer l'indentation (la valeur d'une tab en fait), j'ai utilisé QPlainTextEdit::setTabStopWidth(). Mais la valeur est en pixels, et j'aurais voulu plutôt la fixer en nombre de caractères (j'utilise une police monospace). Est-ce qu'il y aurait un moyen de récupérer à l'exécution la largeur en pixels d'un caractère ?

    Autre détail, lorsqu'on sélectionne un bloc de texte et qu'on appuie sur tab, le texte est remplacé par le caractère tab. Pour qu'au lieu de ça, on indente tout le bloc, j'imagine qu'il faut réimplémenter keyPressEvent() et ensuite insérer une tab au début de chaque ligne. J'ai bon ou il y a plus simple ?

    Merci d'avance !
    (j'aurai sûrement d'autres questions quand je me pencherai sur l'auto complétion ou la numérotation des lignes)

  8. #8
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Pour ton problème, je te recommande ceci : http://qt.developpez.com/doc/latest/qfontmetrics.html
    Et en ce qui concerne les tabulations, il n'y a apparemment pas d'autre moyen que de faire ceci (non testé) dans le keyPressEvent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    QTextCursor cur = textEdit->textCursor();
    QString str = cur.selectedText();
    str.replace("\n", "\t\n");
    cur.removeSelectedText();
    cur.insertText(str);

  9. #9
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Merci de ta réponse, avec QFontMetrics j'ai pu fixer la largeur de tabulation comme je le voulais, voici le code (dans une classe héritant de QPlainTextEdit, les 2 dernières lignes) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    setLineWrapMode(QPlainTextEdit::NoWrap);
    QFont font("Monospace", 10);
    font.setStyleHint(QFont::Courier);
    document()->setDefaultFont(font);
    QFontMetrics fontMetrics(font);
    setTabStopWidth(fontMetrics.width(' ') * 4); // Pixel size of 4 space characters
    Par contre en ce qui concerne l'indentation de plusieurs lignes d'un coup, je n'ai pas encore réussi. Le texte renvoyé ne contient pas de "\n" mais un autre caractère :
    the text will contain a Unicode U+2029 paragraph separator character instead of a newline \n character
    J'ai essayé de faire le remplacement comme ceci (j'ai trouvé le caractère à mettre sur un site) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    str.replace("\u2029", "\t\n");
    ..mais les remplacements ne sont toujours pas faits.

    Outre ce problème, je pense que ta solution ne fonctionnerait pas à tous les coups car si l'on sélectionne un bloc en commençant au milieu d'une ligne (ou en terminant au milieu d'une autre), le texte renvoyé ne contient que la sélection alors que je devrais insérer une tabulation au début de la ligne (début qui est hors sélection du coup). Donc je crois qu'il va falloir que je récupère le bloc précédent ainsi que le suivant pour appliquer correctement l'indentation. Mais je n'ai pas vu de fonction permettant de récupérer le (ou les) bloc correspondant à la sélection plutôt qu'au curseur.

  10. #10
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    C'est bon j'ai trouvé une solution. Je précise aussi lorsque l'utilisateur sélectionne juste un morceau de ligne ou une seule ligne, ça ne devrait pas indenter mais remplacer la sélection par un tab.

    J'ai fait une fonction un peu générique permettant d'indenter (ou désindenter) une ligne, car j'en aurai besoin pour l'auto-indentation également.

    Voici le code
    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
    void CodeEditor::indentBlock(const QTextBlock& block, int indentLevel)
    {
    	if(!block.isValid() || block.length() == 0 || indentLevel == 0)
    		return;
     
    	QTextCursor cursor(block);
    	// Negative indent level means reducing indent level
    	for(int i=0; i>indentLevel && block.text().at(0) == '\t'; --i)
    		cursor.deleteChar();
    	for(int i=0; i<indentLevel; ++i)
    		cursor.insertText("\t");
    }
     
    void CodeEditor::keyPressEvent(QKeyEvent* e)
    {
    	if(e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab)
    	{
    		QTextCursor cursor = textCursor();
    		if(!cursor.hasSelection())
    		{
    			QPlainTextEdit::keyPressEvent(e);
    			return;
    		}
     
    		int beginBlockIndex = document()->findBlock(cursor.selectionStart()).blockNumber();
    		int endBlockIndex = document()->findBlock(cursor.selectionEnd()).blockNumber();
     
    		// If selection is just one line
    		if(beginBlockIndex == endBlockIndex)
    		{
    			QPlainTextEdit::keyPressEvent(e);
    			return;
    		}
     
    		int indentLevel = 1;
    		if(e->key() == Qt::Key_Backtab)
    			indentLevel = -1;
     
    		cursor.beginEditBlock();
     
    		for(int i=beginBlockIndex; i<=endBlockIndex; ++i)
    			indentBlock(document()->findBlockByNumber(i), indentLevel);
     
    		cursor.endEditBlock();
    	}
    	else
    		QPlainTextEdit::keyPressEvent(e);
    }
    Il ne faut pas oublier d'appeler la fonction de la classe mère dans les autres cas pour que le widget gère normalement la saisie, sinon on court-circuite la saisie de texte.

  11. #11
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Finalement ma coloration syntaxique ne fonctionne pas complètement. Je me suis basé sur l'exemple de Qt, et au niveau de la coloration des chaînes l'expression régulière QRegExp("\".*\"") me colore tout ce qui est entre quotes et ne tient pas compte des paires de quotes.

    Exemple : cout << "string1" << variable << "string2" << endl;
    Tout ce qui est souligné sera coloré.

    Je ne suis pas expert en expressions régulières, je ne vois pas comment faire simple. Pour moi le seul moyen serait de parcourir toute la ligne (et encore une chaine pourrait être sur plusieurs lignes, ce qui complique) et traiter les quotes par paires.

    Quelqu'un aurait une idée plus simple ? Merci d'avance !

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968

  13. #13
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    J'aurais dû mieux chercher, merci pour cette astuce, ça fonctionne. J'en ai profité pour améliorer l'expression régulière qui ne prend plus les quotes précédées d'un backslash comme fin de chaine :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    QRegExp exp("\".*[^\\\\]\"");
    exp.setMinimal(true);

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 12/04/2016, 15h29
  2. intégrer du code R dans une application java
    Par supcomingenieur dans le forum R
    Réponses: 3
    Dernier message: 04/06/2013, 13h48
  3. Réponses: 13
    Dernier message: 31/03/2010, 10h35
  4. injection de code dans une application
    Par youp_db dans le forum C
    Réponses: 16
    Dernier message: 21/07/2006, 12h33
  5. [débutante]Intégrer flash dans une application java
    Par bouba83 dans le forum Interfaces Graphiques en Java
    Réponses: 6
    Dernier message: 11/05/2006, 11h11

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