如何为 QTableWidget 添加自动完成
How to add Autocompletion for QTableWidget
我想做的是开始在 table 单元格中输入一些数据,它会显示完成建议,但到目前为止没有成功。
我尝试在单元格中添加 QLineEdit,但有没有办法在不将 QLineEdit 用作 cellWidget 的情况下完成此操作?
编辑:
通过覆盖 QItemDelegate 使其工作 class
Autocomplete_Delegate.h
#include <QItemDelegate>
#include <QModelIndex>
#include <QLineEdit>
#include <QCompleter>
class Autocomplete_Delegate : public QItemDelegate {
public:
Autocomplete_Delegate(QObject *parent, QStringList model);
~Autocomplete_Delegate();
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
private:
QStringList model;
};
Autocomplete_Delegate..cpp
Autocomplete_Delegate::Autocomplete_Delegate(QObject *parent, QStringList model) : QItemDelegate(parent), model(model) {}
Autocomplete_Delegate::~Autocomplete_Delegate() {
model.clear();
}
QWidget *Autocomplete_Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
QWidget *editor = QItemDelegate::createEditor(parent, option, index); //* Create the editor so it looks native to the tablewidget
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); //* create a linedit so it behaves like a line edit and cast the editor to line edit
QCompleter *completer = new QCompleter(model, parent); //* make a completer and pass in the wordlist
completer->setCaseSensitivity(Qt::CaseInsensitive); //* set the case senstivity
lineEdit->setCompleter(completer); //* set the completor on line edit
return lineEdit;
}
void Autocomplete_Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const {
QString data = index.model()->data(index, Qt::EditRole).toString(); //* get the data from the model -> the cell
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
lineEdit->setText(data); //* set the data in the editor
}
感谢@eyllanesc 的想法。
您可以使用与 QTableWidgetItem 关联的角色,并使用委托创建一个 QCompleter,您的模型将在其中建立和更新。
#include <QtWidgets>
enum CustomRoles{
ListCompleterRole = Qt::UserRole + 1000
};
class CompletedDelegate: public QStyledItemDelegate{
public:
using QStyledItemDelegate::QStyledItemDelegate;
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const{
QWidget* editor = QStyledItemDelegate::createEditor(parent, option, index);
if(QLineEdit *le = qobject_cast<QLineEdit *>(editor)){
QStringListModel *model = new QStringListModel(le);
QCompleter *completer = new QCompleter(le);
completer->setModel(model);
le->setCompleter(completer);
}
return editor;
}
void setEditorData(QWidget *editor, const QModelIndex &index) const{
QStyledItemDelegate::setEditorData(editor, index);
if(QLineEdit *le = qobject_cast<QLineEdit *>(editor)){
if(QCompleter *completer = le->completer()){
if(QStringListModel *model = qobject_cast<QStringListModel *>(completer->model())){
QVariant v = index.data(CustomRoles::ListCompleterRole);
if (v.canConvert<QStringList>()){
QStringList options = v.value<QStringList>();
model->setStringList(options);
}
}
}
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStringList words = {
"astonishing",
"agreement",
"appeal",
"autonomy",
"accompany",
"articulate",
"article",
"amuse",
"advertise",
"admiration"
};
QTableWidget w(1, 1);
CompletedDelegate *delegate = new CompletedDelegate(&w);
w.setItemDelegate(delegate);
QTableWidgetItem *item = new QTableWidgetItem;
item->setData(CustomRoles::ListCompleterRole, words); // update options
w.setItem(0, 0, item);
w.show();
return a.exec();
}
我想做的是开始在 table 单元格中输入一些数据,它会显示完成建议,但到目前为止没有成功。
我尝试在单元格中添加 QLineEdit,但有没有办法在不将 QLineEdit 用作 cellWidget 的情况下完成此操作?
编辑:
通过覆盖 QItemDelegate 使其工作 class
Autocomplete_Delegate.h
#include <QItemDelegate>
#include <QModelIndex>
#include <QLineEdit>
#include <QCompleter>
class Autocomplete_Delegate : public QItemDelegate {
public:
Autocomplete_Delegate(QObject *parent, QStringList model);
~Autocomplete_Delegate();
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
private:
QStringList model;
};
Autocomplete_Delegate..cpp
Autocomplete_Delegate::Autocomplete_Delegate(QObject *parent, QStringList model) : QItemDelegate(parent), model(model) {}
Autocomplete_Delegate::~Autocomplete_Delegate() {
model.clear();
}
QWidget *Autocomplete_Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
QWidget *editor = QItemDelegate::createEditor(parent, option, index); //* Create the editor so it looks native to the tablewidget
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); //* create a linedit so it behaves like a line edit and cast the editor to line edit
QCompleter *completer = new QCompleter(model, parent); //* make a completer and pass in the wordlist
completer->setCaseSensitivity(Qt::CaseInsensitive); //* set the case senstivity
lineEdit->setCompleter(completer); //* set the completor on line edit
return lineEdit;
}
void Autocomplete_Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const {
QString data = index.model()->data(index, Qt::EditRole).toString(); //* get the data from the model -> the cell
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
lineEdit->setText(data); //* set the data in the editor
}
感谢@eyllanesc 的想法。
您可以使用与 QTableWidgetItem 关联的角色,并使用委托创建一个 QCompleter,您的模型将在其中建立和更新。
#include <QtWidgets>
enum CustomRoles{
ListCompleterRole = Qt::UserRole + 1000
};
class CompletedDelegate: public QStyledItemDelegate{
public:
using QStyledItemDelegate::QStyledItemDelegate;
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const{
QWidget* editor = QStyledItemDelegate::createEditor(parent, option, index);
if(QLineEdit *le = qobject_cast<QLineEdit *>(editor)){
QStringListModel *model = new QStringListModel(le);
QCompleter *completer = new QCompleter(le);
completer->setModel(model);
le->setCompleter(completer);
}
return editor;
}
void setEditorData(QWidget *editor, const QModelIndex &index) const{
QStyledItemDelegate::setEditorData(editor, index);
if(QLineEdit *le = qobject_cast<QLineEdit *>(editor)){
if(QCompleter *completer = le->completer()){
if(QStringListModel *model = qobject_cast<QStringListModel *>(completer->model())){
QVariant v = index.data(CustomRoles::ListCompleterRole);
if (v.canConvert<QStringList>()){
QStringList options = v.value<QStringList>();
model->setStringList(options);
}
}
}
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStringList words = {
"astonishing",
"agreement",
"appeal",
"autonomy",
"accompany",
"articulate",
"article",
"amuse",
"advertise",
"admiration"
};
QTableWidget w(1, 1);
CompletedDelegate *delegate = new CompletedDelegate(&w);
w.setItemDelegate(delegate);
QTableWidgetItem *item = new QTableWidgetItem;
item->setData(CustomRoles::ListCompleterRole, words); // update options
w.setItem(0, 0, item);
w.show();
return a.exec();
}