QTextCursor: Auswahl verändern

Alles rund um die Programmierung mit Qt
Antworten
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

QTextCursor: Auswahl verändern

Beitrag von phlox81 »

Hallo,

hab da gerade ein kleines Problem, und zwar habe ich ein QTextEdit mit QCompleter.
Nun möchte ich die korrekte Auswahl ermöglichen.

Mein bisheriger Code:

Code: Alles auswählen

QString QContextMenuTextEdit::textUnderCursor() const
 {
     QTextCursor tc = textCursor();
     tc.movePosition(QTextCursor::PreviousWord);//so klappt es auch beim Tippen im Text
     tc.select(QTextCursor::WordUnderCursor);
     return tc.selectedText();
 }
Ich habe hier mit movePosition ein ersten fix schon geschafft, aber es gibt noch ein großes Problem:
gewisse Elemente bei mir enthalten nicht nur a-z und 0-9 sondern auch z.b. ':', in dieser Situation verschwindet die auswahl sobald das : getippt wurde.
Leider weiss ich nicht wirklich, wie ich nun die korrekte Textauswahl da oben hinbekomme, die Doku habe ich schon dazu durch.
Auch finde ich keine Methode für ein setselection(begin,end) oder ähnliches.

Wie muss ich das in QT lösen?

phlox
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Code: Alles auswählen

bool QTextCursor::movePosition ( MoveOperation operation, MoveMode mode = MoveAnchor, int n = 1 )
Und um die Wortgrenze zu finden, must du den Text halt selbst durchgehen.
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

upsala hat geschrieben:

Code: Alles auswählen

bool QTextCursor::movePosition ( MoveOperation operation, MoveMode mode = MoveAnchor, int n = 1 )
Und um die Wortgrenze zu finden, must du den Text halt selbst durchgehen.
Und genau das verstehe ich nicht. Gut, ich kann da von character zu character gehen, aber wie greif ich drauf zu?
Hab da nirgends in der doku eine at, getCharacter oder sonstige Methode gesehen, die mir verrät, welches Zeichen ich an der aktuellen Position habe.

phlox
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

QTextCursor::selectedText()
in Kombination mit dem move.
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

upsala hat geschrieben:QTextCursor::selectedText()
in Kombination mit dem move.
Ähm, ich dachte das gibt die Selection zurück.
Erweitert MovePosition die?
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Steht in deiner Doku nichts darüber?
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

http://doc.trolltech.com/4.5/qtextcurso ... lectedText

Kann das gerade wohl nicht testen.
Aber unter selectedText würde ich genau das erwarten, das es die Selection wiedergibt.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Ein kleines Beispiel. Ich habe ein TextEdit, in dem steht momentan:

Code: Alles auswählen

aber die katze war nicht im sack:mann
Der Cursor befgindet sich am Ende der Zeile, also hinter mann.
Ich möchte jetzt sack:mann selektieren. Bitte entschuldige das Python, aber solche Experimente mach ich immer "live" in der Python-Console :)

Code: Alles auswählen

>>> c2 = edit.document().find( " ", edit.textCursor().position(), QTextDocument.FindBackward )
>>> c2.setPosition(c2.position())
>>> c2.setPosition( edit.textCursor().position(), QTextCursor.KeepAnchor )
>>> print c2.selectedText()
sack:mann
das "c2.setPosition(c2.position())" ist notwendig, da c2.position()==28 und c2.anchor()==27, und die 27 ist VOR dem Leerzeichen, was wir ja nicht in der Selection mithaben wollen.

Das ganze wird noch netter, wenn du statt nem QString ne QStringList zurückgeben würdest :P Denn wenn der User den Cursor der aktuellen Eingabe nach links setzt, weil er beim Tippen einen Buchstaben vergessen hat. Wenn man dann stur nur den letzten Seperator suchst und bis zum aktuellen Cursor die Completion erstellt, bekommt der User wohl mehr Completions zurück als er eigentlich will. Nun könntest du eben nocht zusätzlich bis zum nächsten Seperator suchen und das als Completion mit höherer Priorität werten, also in dem Popup weiter oben stehen haben.

Ach ja, ersetze in "find()" den String " " (Leerzeichen) durch eine QRegExp, um nicht nur " " als Seperator zu bekommen, sondern alles was für dich wichtig ist.

Grüße
Franz
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

Ja, am praktischsten fände ich es wenn ich einfach mit einer RegEx die Auswahl erledigen könnte.
Sowas wie "*[a-zA-z:0-9]" halt.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Sowas wie "[^a-zA-z:0-9]" halt.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Und dann gibts Probleme, wenn man mal andere Zeichen als 0-9, a-z und A-Z haben will...
Außerdem weiß ich nicht, ob man mit QRegExp von einer Position aus überhaupt rückwärts finden kann ;)

Ich hab mit der RegExp eigentlich nicht gedacht die ganze Completion-Expression zu finden, sondern nur den (letzten) Word-Separator. Dass halt neue Wörter nicht nur nach einem " " (blank) anfangen, sondern z.B. auch nach nem ; usw.
Also etwa so:

Code: Alles auswählen

QString str("Hello.world mit;Separatoren");
QRegExp rx("[.| |;]");
int pos = 0;
while ((pos = rx.indexIn(str, pos)) != -1) {
    qDebug() << "Separator at" << pos;
    pos += rx.matchedLength();
}
ergibt

Code: Alles auswählen

Separator at 5
Separator at 11
Separator at 15
Und auf das obige Beispiel angewandt:

Code: Alles auswählen

>>> c2 = edit.document().find( QRegExp("[.| |;]"), edit.textCursor().position(), QTextDocument.FindBackward )
>>> c2.setPosition(c2.position())
>>> c2.setPosition( edit.textCursor().position(), QTextCursor.KeepAnchor )
>>> print c2.selectedText()
sack:mann
findet als separator " ", "." und ";" ok.
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

franzf hat geschrieben:Und dann gibts Probleme, wenn man mal andere Zeichen als 0-9, a-z und A-Z haben will...
Außerdem weiß ich nicht, ob man mit QRegExp von einer Position aus überhaupt rückwärts finden kann ;)
Ja das stimmt, nach einem Word-trenner zu suchen ist evtl. auch sinnvoller.

Funktioniert!
Musste nur noch in einer anderen Methode(KeyPressEvent) die Wortgrenzen anpassen, dann klappts auch mit :, sonst wird da ausgeblendet und danach wieder eingeblendet.

phlox
Antworten