2011-01-31 9 views

risposta

10

si dovrebbe essere in grado di forzare la finestra pop-up di completer per ottenere dimostrato ancora una volta il testo riga di modifica viene cancellata utilizzando QCompliter::complete Slot:

lineEdit->completer()->complete(); 

Ecco come si può fare:

  • definire TextChanged slot per il tuo lineedit;
  • ignora il metodo customEvent per la finestra;
  • nello slot textChanged invia l'evento utente alla finestra ogni volta che il testo di lineedit ha lunghezza zero;
  • nel metodo customEvent mostrare il completamento ogni volta che viene ricevuto un evento utente;

Di seguito è riportato un esempio:

mainwindow.h:

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

protected: 
    void customEvent(QEvent * event); 

private: 
    Ui::MainWindow *ui; 

private slots: 
    void on_lineEdit_textChanged(QString); 
}; 

mainwindow.cpp:

class CompleteEvent : public QEvent 
{ 
public: 
    CompleteEvent(QLineEdit *lineEdit) : QEvent(QEvent::User), m_lineEdit(lineEdit) { } 

    void complete() 
    { 
     m_lineEdit->completer()->complete(); 
    } 

private: 
    QLineEdit *m_lineEdit; 
}; 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    QStringList wordList; 
    wordList << "one" << "two" << "three" << "four"; 

    QLineEdit *lineEdit = new QLineEdit(this); 
    lineEdit->setGeometry(20, 20, 200, 30); 
    connect(lineEdit, SIGNAL(textChanged(QString)), SLOT(on_lineEdit_textChanged(QString))); 

    QCompleter *completer = new QCompleter(wordList, this); 
    completer->setCaseSensitivity(Qt::CaseInsensitive); 
    completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion); 
    lineEdit->setCompleter(completer); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::customEvent(QEvent * event) 
{ 
    QMainWindow::customEvent(event); 
    if (event->type()==QEvent::User) 
     ((CompleteEvent*)event)->complete(); 
} 

void MainWindow::on_lineEdit_textChanged(QString text) 
{ 
    if (text.length()==0) 
     QApplication::postEvent(this, new CompleteEvent((QLineEdit*)sender())); 
} 

speranza che questo aiuti, riguarda

+0

funziona come un fascino, grazie! Stavo cercando di fare qualcosa di simile con un QTimer :: singleShot, ma per qualche motivo non funzionava. –

0

Ecco la mia soluzione basato sulla risposta di serge_gubenko. Questa classe utilizza QStringListModel, ma può essere facilmente sostituita con qualsiasi altro modello.

Completer_line_edit.h

#include <QLineEdit> 
#include <QStringListModel> 
#include <QTimer> 

/*! Line edit widget with auto completion based on QStringListModel. 
    Modified behaviour: completion list will appear even when contents of 
    line edit is empty. Full list of options will be showed when line edit 
    has focus and is empty. 
    */ 
class Completer_line_edit : public QLineEdit { 
    Q_OBJECT 
public: 
    explicit Completer_line_edit(QWidget *parent = 0); 

    //! Set list of options used for copmletion. 
    inline void set_list(QStringList list) { model.setStringList(list); } 

private: 
    QStringListModel model; 
    void focusInEvent(QFocusEvent *e); 
    void customEvent(QEvent* e); 
    QTimer timer; 

private slots: 
    void slot_text_edited(); 
    void slot_call_popup(); 

}; 

Completer_line_edit.cpp

#include "Completer_line_edit.h" 
#include <QCompleter> 
#include <QEvent> 
#include <QApplication> 

Completer_line_edit::Completer_line_edit(QWidget *parent) : 
    QLineEdit(parent) 
{ 
    setCompleter(new QCompleter()); 
    completer()->setModel(&model); 
    completer()->setCompletionMode(QCompleter::PopupCompletion); 
    completer()->setCaseSensitivity(Qt::CaseInsensitive); 
    connect(this, SIGNAL(textEdited(QString)), this, SLOT(slot_text_edited())); 
} 

void Completer_line_edit::focusInEvent(QFocusEvent *e) { 
    QLineEdit::focusInEvent(e); 
    // force completion when line edit is focued in 
    completer()->complete(); 
} 

void Completer_line_edit::slot_text_edited() { 
    qDebug() << "text edited"; 
    // force to show all items when text is empty 
    completer()->setCompletionMode(text().isEmpty()? QCompleter::UnfilteredPopupCompletion: QCompleter::PopupCompletion); 
    if (text().isEmpty()) { 
    // completion list will be hidden now; we will show it again after a delay 
    timer.singleShot(100, this, SLOT(slot_call_popup())); 
    } 
} 

void Completer_line_edit::slot_call_popup() { 
    // apparently, complete() works only in event handler 
    QApplication::postEvent(this, new QEvent(QEvent::User)); 
} 

void Completer_line_edit::customEvent(QEvent *e) { 
    QLineEdit::customEvent(e); 
    // force completion after text is deleted 
    completer()->complete(); 
} 
Problemi correlati