PDA

View Full Version : MyCompleter on MyLineEdit



pkj
28th August 2012, 15:08
The default behaviour of QCompleter on QLineEdit set using function QLineEdit::setCompleter() is to take all of the string in QLineEdit::text. So if I want a behaviour where in a QTreeModelCompleter parses parts of QLineEdit::text() [ex: A.B.C && C.D.E] it is not possible with the default behaviour. As A.B.C will work but after it all of the text is given to my Completer and it doesn't work.
To avoid it I decided to have my own LineEdit inheriting from QLineEdit with this format:


class LineEdit : public QLineEdit
{
Q_OBJECT
public:
explicit LineEdit(QWidget *parent = 0);
protected:
signals:
private slots:
void insertCompletion(QString);
void textEditedSlot(const QString &);
private:
QCompleter* completer;
QString textUnderCursor();
};

LineEdit::LineEdit(QWidget *parent) : QLineEdit(parent)
{
completer= new TreeModelCompleter(this);//TreeModelCompleter is my implementation of QCompleter, works ok with qtextedit
completer->setWidget(this);
QObject::connect(completer, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString)));
QObject::connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEditedSlot(QString)));
}

void LineEdit::insertCompletion(QString completion)
{
bool done = false;
QString rep;
int initPos = cursorPosition();
int pos = initPos;
QString t = text();
while(!done){
bool moved=true;
if(pos == 0) moved = false;
else { --pos; rep = t.at(pos) + rep; }
if(!moved) done = true;
else if(rep.contains(QRegExp("[\\s+-&!,|<>?/ \\(\\) \\{\\} ]")))
{
if(!done) rep.remove(0, 1);
done = true;
++pos;
}
}
setText(t.replace(pos, initPos-pos+1, completion));
}

void LineEdit::textEditedSlot(const QString &text)
{

QString completionPrefix = textUnderCursor();
if (completionPrefix != completer->completionPrefix()) {
completer->setCompletionPrefix(completionPrefix);
completer->popup()->setCurrentIndex(completer->popup()->model()->index(0,0));
}
QRect cr = cursorRect();
cr.setWidth(completer->popup()->sizeHintForColumn(0)
+ completer->popup()->verticalScrollBar()->sizeHint().width());
completer->complete(cr); // popup it up!
}

QString LineEdit::textUnderCursor()
{
bool done = false;
QString rep;
int initPos = cursorPosition();
int pos = initPos;
QString t = text();
while(!done){
bool moved=true;
if(pos == 0) moved = false;
else {--pos;rep = t.at(pos) + rep; }
if(!moved) done = true;
else if(rep.contains(QRegExp("[\\s+-&!,|<>?/ \\(\\) \\{\\} ]")))
{
if(!done) rep.remove(0, 1);
done = true;
++pos;
}
}

if(!thisString.isEmpty() && rep.contains(QString("this"))){
rep = rep.replace(QString("this"), thisString);
}
return rep;
}


Now the Problem is after typing in say A no event is taken in by LineEdit. I tried checking with implementing event functions of LineEdit and MyCompleter. So a QKeyEvent of '.' comes to LineEdit but no editchanged signal arrives! LineEdit is rejecting QKeyEvents of '.' For if LineEdit is receiving the event of '.' it should result in text() being changed, leading to fire of textEdited() signal. But is not happening. I don't get it.