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
5
A
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
Đâ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();
}
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. –