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).
    example:
    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","...")
    4.done

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

    thanks



  • 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
    {
    public:
    TableDelegate( QWidget* parent = 0 ) : QStyledItemDelegate( parent ){}

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

    };@
    //=====================================================================
    @class EditFieldDelegate : public TableDelegate
    {
    Q_OBJECT
    public:
    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 );

    signals:
    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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.