2011-01-31 3 views
5

QLineEditがあり、QCompleterオブジェクトが関連付けられています。ユーザが少なくとも1つの文字を入力すると、QCompleterのポップアップメニューが表示されますが、ユーザが最後の文字を削除すると(フィールドは空のままです)、ポップアップが消えます。 QLineEditのテキストが空であっても表示させる方法はありますか?あなたがラインエディットテキストがQCompliter::completeスロットを使用することによって消去されると示さ取得するコンプリータのポップアップウィンドウを強制することができるはずQCompleterを含むQLineEditは、空のテキストフィールドを持つQCompleterのポップアップメニューを表示しません。

答えて

10

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

は、ここであなたがそれを行うことができます方法は次のとおりです。

  • はtextChangedを定義しますあなたのライン編集のためのスロット。
  • ウィンドウのcustomEventメソッドをオーバーライドします。
  • textChangedスロットlineeditのテキストの長さがゼロの場合は常に、ユーザイベントをウィンドウに送信します。
  • のcustomEventメソッドでは、ユーザーイベントが受信されるたびにコンプリートが表示されます。以下は

例です。

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())); 
} 

希望は、ここで

+0

作品、ありがとうございました!私はQTimer :: singleShotと同様のことをしようとしていましたが、何らかの理由でそれが動作していませんでした。 –

0

について私の解決策れますserge_gubenkoの答えに基づいています。このクラスはQStringListModelを使用しますが、他のモデルと簡単に置き換えることができます。魔法のように

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(); 
} 
関連する問題