Important: Please read the Qt Code of Conduct -

Autocomplete textbox

  • hi Qt community
    i'm looking for the way of implementing dynamic QCompleter.
    let me explain what i need
    i have a phonebook table (in MySQL) with name,phoneNumbers columns and it contains about 30,000 records (so i can't simply use QCompleter with a QStringList or something like that).
    so, i need a textbox that sends a query to the database (with textchanged signal for example) and probably a code that updates QCompleter with the query's result and shows the suggestions(like AJAX completers in the web).
    1.user type key "s" into the textbox.
    2.a query "SELECT blablabla WHERE LIKE %".(only records starting with the s character)
    3.textbox shows the suggestions.("stan","smith","steve","...")

    and after all, my QLineEdit is in the custom ItemView table(with custom itemdelegate),so i can't use subclassed QLineEdit.


  • Hi Wild Pointer,
    the first part isn't that difficult.
    QLineEdit generate a signal like textChanged().
    This signal will be send to a second thread which will check for a new query of your database.
    The response will the be send to the gui thread to actualize the QCompleter.
    The word list is provided as a QAbstractItemModel which then can be used to update the QCompleter.

    I hope this will help you.

  • thank you for your respond messi
    i already have the complete QLineEdit+SQL autocompleter class.
    the main problem is the QTableView with QItemDelegate.
    when you use your custom QLineEdit class, the QTableView(or maybe QItemDelegate::createEditor) make your popup(or inline)completion buggy(small window will show & hide and that will not work at all).
    did you tried QTableView+QItemDelegate+QLineEdit together ?

  • Yes I used it. It can be difficult. Here is how I did it but with out completer:

    //class TableDelegate is not necessary. You can use QStyledItemDelegate directly
    @class TableDelegate : public QStyledItemDelegate
    TableDelegate( QWidget* parent = 0 ) : QStyledItemDelegate( parent ){}

    virtual void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;

    @class EditFieldDelegate : public TableDelegate
    EditFieldDelegate( QWidget* parent = 0 );
    QWidget createEditor(QWidget parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData( QWidget
    editor, const QModelIndex& index ) const;
    void setModelData( QWidget
    editor, QAbstractItemModel* model, const QModelIndex& index ) const;
    void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
    type );

    void editorClosing();
    void selectionChanged( int row, int column ) const;
    void textChanged(const QString& text);

    private slots:
    void editorIsClosing( QWidget * editor, QAbstractItemDelegate::EndEditHint hint );
    @EditFieldDelegate::EditFieldDelegate( IDataClientManager* dataClientManager, const QString& connectName, bool mpDependent, QWidget* parent )
    : TableDelegate( parent )--

    @QWidget* EditFieldDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem&, const QModelIndex& index) const

    QLineEdit* editor = new QLineEdit( parent );
    editor->showLabel( false );
    return editor;


    @void EditFieldDelegate::setEditorData( QWidget* editor, const QModelIndex& index ) const
    editor->setFocus( Qt::OtherFocusReason );
    QString data = index.model()->data( index, Qt::EditRole ).toString();
    QLineEdit* field = qobject_cast<QLineEdit*>( editor );

    if( field )
        field->setText( data );


    @void EditFieldDelegate::setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const
    QLineEdit* field = qobject_cast<QLineEdit*>( editor );

    if( field )
        model->setData( index, field->getLineEdit()->text(), Qt::EditRole );


    @void EditFieldDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& ) const
    editor->setGeometry( option.rect );
    // In your code where you initialize the table you would need the folllowing:
    EditFieldDelegate* editDelegate = new EditFieldDelegate( );
    table->setItemDelegateForColumn( 2, editDelegate );
    connect( editDelegate, SIGNAL(textChanged(QString)), this, SLOT(updateTableItem()) );@

Log in to reply