我正在尝试为 QLineEdit 实现自动完成。
在这里看我的代码:
#ifndef COMPLETER_H
#define COMPLETER_H
#include <QCompleter>
#include <QString>
#include <QStringList>
#include <QLineEdit>
class Completer:public QCompleter
{
Q_OBJECT
public:
explicit Completer(QStringList stringList, QObject *parent=0);
virtual QString pathFromIndex(const QModelIndex &index)const;
virtual QStringList splitPath(const QString&)const;
public slots:
void onLineEditTextChanged() const;
private:
mutable int cursorPos_;
};
class ExpressionLineEdit: public QLineEdit
{
Q_OBJECT
public:
explicit ExpressionLineEdit(QWidget *parent=0);
private:
QStringList stringList;
Completer *completer_;
};
#endif // COMPLETER_H
#include <completer.h>
#include <QDebug>
Completer::Completer(QStringList stringList, QObject *parent)
: QCompleter(stringList,parent)
, cursorPos_(-1)
{
}
ExpressionLineEdit::ExpressionLineEdit(QWidget* parent)
: QLineEdit(parent)
{
stringList << "minRoute" << "minPitch" << "minSpacing";
completer_ = new Completer(stringList, this);
setCompleter(completer_);
QObject::connect(this, SIGNAL(textChanged(const QString&)),
completer_, SLOT(onLineEditTextChanged()));
QObject::connect(this, SIGNAL(cursorPositionChanged(int, int)),
completer_, SLOT(onLineEditTextChanged()));
}
QString Completer::pathFromIndex(const QModelIndex &index) const
{
QString newStr = index.data(Qt::EditRole).toString();
ExpressionLineEdit *lineEdit = qobject_cast<ExpressionLineEdit*>(parent());
QString str = lineEdit->text();
int prevSpacePos = str.mid(0, lineEdit->cursorPosition()).lastIndexOf(' ');
int curPos = lineEdit->cursorPosition();
int nextSpacePos = str.indexOf(' ', curPos);
if (nextSpacePos == -1) {
nextSpacePos = str.size();
}
QString part1 = str.mid(0, prevSpacePos + 1);
QString pre = str.mid(prevSpacePos + 1, curPos - prevSpacePos - 1);
QString post = str.mid(curPos, nextSpacePos - curPos);
QString part2 = str.mid(nextSpacePos);
onLineEditTextChanged();
cursorPos_ = curPos + newStr.size() - pre.size();
return part1 + newStr + part2;
}
void Completer::onLineEditTextChanged() const
{
qDebug() << "Completer::onLineEditTextChanged()" << cursorPos_;
if (cursorPos_ != -1) {
ExpressionLineEdit *lineEdit = qobject_cast<ExpressionLineEdit*>(parent());
lineEdit->setCursorPosition(cursorPos_);
cursorPos_ = -1;
}
}
QStringList Completer::splitPath(const QString &path) const
{
cursorPos_ = -1;
ExpressionLineEdit *lineEdit = qobject_cast<ExpressionLineEdit*>(parent());
QString text = lineEdit->text();
QStringList stringList;
QString str;
int index = text.mid(0,lineEdit->cursorPosition()).lastIndexOf(' ');
str = text.mid(index, lineEdit->cursorPosition()-index);
str.trimmed();
str.replace(" ", "");
stringList << str;
onLineEditTextChanged();
return stringList;
}
#include <completer.h>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ExpressionLineEdit le;
le.show();
return a.exec();
}
对于此代码,ExpressionLineEdit 和 Completer 可以正常工作(如预期的那样)。
但是当我尝试将 QTreeView 和 QSyledItemDelegate 设置为时,行为发生了变化。我试图重新实现QSyledItemDelegate的eventFilter函数,但它不说话。我尝试将 ExpressionLineEdit 设置为其他 QWidget 并将 QWidget 设置为 QTreeView (因为 QSyledItemDelegate 不能直接与 ExpressionLineEdit 一起使用),但它再次没有帮助。
这是带有 QTreeView 和 QSyledItemDelegate 的代码。
#include <QTreeView>
#include <QVBoxLayout>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
#include <Completer.h>
class QEvent;
class Delegate:public QStyledItemDelegate
{
public:
Delegate(QObject* parent = 0)
:QStyledItemDelegate(parent){}
bool eventFilter(QObject* editor,QEvent* event){return false;}
virtual bool editorEvent ( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex& index){return false;}
QWidget* createEditor(QWidget* parent,const QStyleOptionViewItem &option,const QModelindex &index) const
{
if(index.column() != 1) return 0;
QWidget* w = new QWidget(parent);
ExpressionLineEdit *le = new ExpressionLineEdit(w);
QVBoxLayout* lay = new QVBoxLayout(w);
lay->setContentsMargins(0, 0, 0, 0);
lay->addWidget(le);
w->setLayout(lay);
return w;
}
};
class Tree:public QTreeView
{
public:
Tree(QWidget* parent = 0)
:QTreeView(parent)
{
QStandardItemModel *model = new QStandardItemModel(this);
model->setRowCount(1);
model->setColumnCount(2);
QStandardItem *item = new QStandardItem("Item");
model->setItem(0,0,item);
setModel(model);
Delegate *d = new Delegate(this);
setItemDelegate(d);
}
void keyPressEvent ( QKeyEvent * event ){}
};
#include <QApplication>
#include <Completer.h>
#include <Tree.h>
int main(int argc, char ** argv)
{
QApplication app(argc,argv);
Tree t;
t.show();
return app.exec();
}
请帮助理解为什么相同的代码在这两种情况下的工作方式不同。请帮助修复 Completer 的行为。