2011-01-31 17 views
5

Tôi có một QLineEdit, với đối tượng QCompleter được liên kết với nó. Nếu người dùng nhập ít nhất một ký tự, trình đơn bật lên từ QCompleter được hiển thị, nhưng khi người dùng xóa ký tự cuối cùng (do đó để trống trường này), cửa sổ bật lên sẽ biến mất. Có cách nào để hiển thị ngay cả khi văn bản của QLineEdit bị trống không?QLineEdit với QCompleter sẽ không hiển thị menu bật lên của QCompleter với trường văn bản trống

Trả lời

10

bạn sẽ có thể để buộc cửa sổ popup Completer của để có được thể hiện khi dòng chỉnh sửa văn bản của bạn bị xóa bằng cách sử dụng QCompliter::complete khe:

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

Đây là cách bạn có thể làm điều đó:

  • xác định TextChanged slot cho lineedit của bạn;
  • ghi đè phương thức tùy chỉnhEvent cho cửa sổ của bạn;
  • trong văn bảnThay đổi vị trí gửi sự kiện của người dùng đến cửa sổ bất cứ khi nào văn bản của dòng ký tự có độ dài bằng 0;
  • trong chương trình phương thức customEvent hoàn thành bất cứ khi nào sự kiện của người dùng được nhận;

Dưới đây là một ví dụ:

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

hy vọng điều này giúp, coi

+0

trình như một say mê, cảm ơn bạn! Tôi đã cố gắng để làm một cái gì đó tương tự với một QTimer :: singleShot, nhưng đối với một số lý do nó không hoạt động. –

0

Đây là giải pháp của tôi dựa trên câu trả lời của serge_gubenko. Lớp này sử dụng QStringListModel, nhưng nó có thể dễ dàng được thay thế bằng bất kỳ mô hình nào khác.

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(); 
} 
Các vấn đề liên quan