Ich brauchte etwas genau so! Bei meinen Tests bemerkte ich jedoch einige Dinge, es gibt einige Dinge, die Sie loswerden können (zum Beispiel QString post wird nicht wirklich verwendet, es kann gelöscht werden). Es scheint auch einen Bug in Ihrer Implementierung zu geben (zumindest aus meinen Tests), wenn Sie eine Liste von Wörtern eingeben, dann gehen Sie zurück, um irgendwo in der Mitte ein Wort einzugeben, wenn Sie mit den Pfeiltasten nach oben/unten gehen In der Autocomplete-Liste wird das erste hervorgehobene Wort an der richtigen Position platziert, danach springt der Cursor jedoch an das Ende (unabhängig vom Slot onLineEditTextChanged()) und ersetzt dann das letzte Wort durch das aus der Autokorrekturliste.
habe ich meine eigene Implementierung, einer der wichtigsten Unterschiede ist meine Implementierung eines Begrenzer Charakter nimmt, und das Zeichen verwendet wird, statt immer einen weißen Raum mit, und ich Es ist der Fehler, die ich oben beschrieben.
DelimitedCompleter.hpp
#ifndef DELIMITEDCOMPLETER_HPP
#define DELIMITEDCOMPLETER_HPP
#include <QCompleter>
class QString;
class QStringList;
/**
* class DelimitedCompleter
*
* QCompleter that supports completing multiple words in a QLineEdit, completed words are separated
* by delimiter.
*/
class DelimitedCompleter : public QCompleter {
Q_OBJECT
public:
DelimitedCompleter(QLineEdit *parent, char delimiter);
DelimitedCompleter(QLineEdit *parent, char delimiter, QAbstractItemModel *model);
DelimitedCompleter(QLineEdit *parent, char delimiter, const QStringList &list);
QString pathFromIndex(const QModelIndex &index) const;
QStringList splitPath(const QString &path) const;
private:
char delimiter;
mutable int cursor_pos = -1;
void connectSignals();
private slots:
void onActivated(const QString &text);
void onCursorPositionChanged(int old_pos, int new_pos);
};
#endif
DelimitedCompleter.cpp
#include "DelimitedCompleter.hpp"
#include <QDebug>
#include <QLineEdit>
#include <QStringList>
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DELIMITEDCOMPLETER PUBLIC METHODS *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DelimitedCompleter::DelimitedCompleter(QLineEdit *parent, char delimiter)
: QCompleter(parent), delimiter(delimiter) {
parent->setCompleter(this);
connectSignals();
}
DelimitedCompleter::DelimitedCompleter(QLineEdit *parent, char delimiter, QAbstractItemModel *model)
: QCompleter(model, parent), delimiter(delimiter) {
parent->setCompleter(this);
connectSignals();
}
DelimitedCompleter::DelimitedCompleter(QLineEdit *parent, char delimiter, const QStringList &list)
: QCompleter(list, parent), delimiter(delimiter) {
parent->setCompleter(this);
connectSignals();
}
QString DelimitedCompleter::pathFromIndex(const QModelIndex &index) const {
QString auto_string = index.data(Qt::EditRole).toString();
QLineEdit *line_edit = qobject_cast<QLineEdit*>(parent());
QString str = line_edit->text();
// If cursor position was saved, restore it, else save it
if(cursor_pos != -1) line_edit->setCursorPosition(cursor_pos);
else cursor_pos = line_edit->cursorPosition();
// Get current prosition
int cur_index = line_edit->cursorPosition();
/**
* NOTE
*
* prev_delimiter_index should actually point at final white space AFTER the delimiter.
*/
// Get index of last delimiter before current position
int prev_delimiter_index = str.mid(0, cur_index).lastIndexOf(delimiter);
while(str.at(prev_delimiter_index + 1).isSpace()) prev_delimiter_index++;
// Get index of first delimiter after current position (or EOL if no delimiter after cursor)
int next_delimiter_index = str.indexOf(delimiter, cur_index);
if(next_delimiter_index == -1) {
next_delimiter_index = str.size();
}
// Get part of string that occurs before cursor
QString part1 = str.mid(0, prev_delimiter_index + 1);
// Get string value from before auto finished string is selected
QString pre = str.mid(prev_delimiter_index + 1, cur_index - prev_delimiter_index - 1);
// Get part of string that occurs AFTER cursor
QString part2 = str.mid(next_delimiter_index);
return part1 + auto_string + part2;
}
QStringList DelimitedCompleter::splitPath(const QString &path) const {
QLineEdit *line_edit = qobject_cast<QLineEdit*>(parent());
QStringList string_list;
int index = path.mid(0,line_edit->cursorPosition()).lastIndexOf(delimiter) + 1;
QString str = path.mid(index, line_edit->cursorPosition()-index).trimmed();
string_list << str;
return string_list;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DELIMITEDCOMPLETER PRIVATE METHODS *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void DelimitedCompleter::connectSignals() {
connect(this, SIGNAL(activated(const QString &)), this, SLOT(onActivated(const QString &)));
connect(qobject_cast<QLineEdit*>(parent()), SIGNAL(cursorPositionChanged(int, int)),
this, SLOT(onCursorPositionChanged(int, int)));
}
void DelimitedCompleter::onActivated(const QString &text) {
cursor_pos = -1;
}
void DelimitedCompleter::onCursorPositionChanged(int old_pos, int new_pos) {
// If old_pos == cursor_pos then we are cycling through autocomplete list
// If not cycling through autocomplete list, then make sure cursor_pos is reset to -1
if(old_pos != cursor_pos) cursor_pos = -1;
}
Der QCompleter für QLineEdit prüft nicht jedes Wort, sondern den gesamten Inhalt. Wenn Ihre Strings "Alpha Omega" wären, würde der Completer Ihnen einen Treffer für diese Saite geben. Sie sollten schließlich QLineEdit ableiten und die Implementierung so einrichten, dass QCompleter für jedes Wort anstelle des gesamten Inhalts verwendet wird. –
Und wie man die Implementierung für QLineEdit, für die QCompleter jedes Wort aber den gesamten Inhalt überprüft? –
Es tut mir leid, aber ich habe nicht die Zeit, Ihnen eine vollständige Implementierung für eine QLineEdit-Subclass zu geben. Außerdem können Sie viel mehr lernen, indem Sie es selbst machen.Schließlich könnten Sie QLineEdits Completer einrichten, um das letzte Wort zu erkennen, das mit 'QCompleter :: setCompletionPrefix (const QString & Präfix) geschrieben wurde;' 'Präfix ist nur Ihr letztes einzelnes Wort, das Sie vervollständigen möchten. –