Seite 1 von 1

Spellchecker

Verfasst: 11. Juni 2008 16:17
von pfid
Hallo,

gibt es bei QT (vllt 4.4 ..?) einen fertigen Spellchecker? Habe momentan 4.3 drauf, kann nichts entsprechendes finden (bei 4.4 auf Anhieb auch nicht).

Momentan führe ich die Rechtschreibprüfung daher von Hand durch, mit aspell und dem durchgehen eines QTextEdit per QTextCursor (Block für Block, Wort für Wort). Funktioniert im Prinzip gut, eine Frage hätt ich dazu allerdings noch.

Wenn ich ein RTF Eingabefeld habe, in dem u. A. auch Wörter unterstrichen sind, dann unterstreicht mir der Spellchecker ein falsches Wort rot. Wenn das Wort korrigiert wird, ist das Wort gar nicht mehr unterstrichen, obwohl es vorher im normalen Text unterstrichen war. Gibts da eine Möglichkeit, mit dem Spellchecker getrennt (doppelt) zu unterstreichen? Bei Thunderbird z. B. ist das so, da unterstreicht der Spellchecker zusätzlich zur normalen Formatierung.

Die Prüfung/Markierung geht bisher so:

Code: Alles auswählen

         do
         {
            cur.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
            
            if (!cur.selectedText().isEmpty())
            {
               normalFormat = errorFormat = cur.charFormat();
               errorFormat.setUnderlineColor(QColor(Qt::red));
               errorFormat.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
               normalFormat.setUnderlineStyle(QTextCharFormat::NoUnderline);
               
               if (spellCheckWord(cur.selectedText()))
                  cur.setCharFormat(errorFormat);
               else
                  cur.setCharFormat(normalFormat);
            }
         }
         while (cur.movePosition(QTextCursor::NextWord, QTextCursor::MoveAnchor));
Das gleiche Problem hab ich dann natürlich auch, wennn ich die Prüfung ausschalten möchte. Wenn da vorher 10 Wörter rot markiert waren, sind die jetzt blind einfach nicht mehr unterstrichen, obwohl sie vorher im Text vielleicht (normal) unterstrichen waren.

Hoffe das war einigermaßen verständlich :)

[edit] Noch was. Gibts eigentlich ne einfachere Methode, um von Wort zu Wort zu springen? Das oben erscheint mir etwas umständlich. Sowas wie

Code: Alles auswählen

 while (document.getNextWord())
wäre schöner.

Verfasst: 16. Juni 2008 17:07
von pfid
Scheint wohl nicht zu gehen. Habe daher noch eine andere Frage:

Per QTextCursor::movePosition() kann ich den Cursor an den Anfang und das Ende eines Wortes schieben, und somit nacheinander jedes Wort markieren und prüfen. So ganz sauber scheint das aber nicht zu funktionieren.

QTextCursor::EndOfWord bringt mich meistens zuverlässig ans Ende eines Wortes, QTextCursor::nextWord stellt mich aber jedesmal vor Character wie ' ', ':', ';' etc. Das heißt, in der Schleife in der ich jedes Wort prüfe, muss ich zusätzlich eine Schleife durchlaufen, in der ich Character für Character das erste Zeichen des Wortes auf o.g. Zeichen prüfe, und ggfs. überspringe. Wenn ich das nicht mache, markiert mir der Spellchecker zum Beispiel nicht "hauss", sondern evtl. ", hauss".

Stell ich mich hier zu blöd an, oder ist das eine Schrulle von Qt?

Hier ist der derzeitige Code zur Wörtersuche:

Code: Alles auswählen

int SpellChecker::getNextWord(QTextCursor* cur)
{
   cur->clearSelection();
   
   do
   {
      // first word?
      
      if (cur->atStart())
         cur->movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
      
      // done when text is selected

      if (!cur->selectedText().isEmpty())
         break;
      
      // else go to next word, next block, or done completely
      
      if (!cur->movePosition(QTextCursor::NextWord, QTextCursor::MoveAnchor))
         if (!cur->movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor))
            return fail;

      cur->movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
         
   } while (cur->selectedText().isEmpty());
   
   return success;
}
Mit diesem Code prüfe ich dann ob das Wort korrekt geschrieben ist, und markiere es entsprechend:

Code: Alles auswählen

      while (getNextWord(&cur) == success)
      {
         if (spellCheckWord(cur.selectedText()) != success)
            cur.mergeCharFormat(errorFormat);
         else
            cur.setCharFormat(normalFormat);
      }
Wie gesagt, so markiert er mir eben den Wortanfang nicht korrekt.

Manchmal kommt es auch vor, dass das Ende des Wortes nicht mehr korrekt markiert wird, nämlich wenn die Check-Methode mit QTextEdit::textChanged() connected ist, und beim tippen Fehler reinkommen. D.h. man tippt "hauss", Cursor steht nach dem letzten s, und man tippt " ist ..." weiter. Dann markiert er zusätzlich zu "hauss" auch noch den nachfolgenden Space.
Ich kann dann (aus irgendeinem Grund) auch nicht mehr mit o.g. Methode über alle Wörter gehen, und die Markierung entfernen; bei den "kaputten" Wort-Enden bleibt die Markierung dann für immer (ist aber wohl schwer nachzuvollziehen ohne dass ich den ganzen Code poste).

Hat da jemand eine Idee?