Closed probonopd closed 3 years ago
// Select the first (or the only) result of the completer
// FIXME: This does not work yet. Why?
// Also see: https://github.com/helloSystem/Menu/issues/14
class AutoSelectFirstFilter : public QObject
{
public:
explicit AutoSelectFirstFilter(QLineEdit *parent) : QObject(parent)
{}
bool eventFilter(QObject *obj, QEvent *e) override
{
QAbstractItemView* l = static_cast<QAbstractItemView*>(obj);
// Try to automatically select the first match of the completer;
if (e->type() == QEvent::KeyPress)
{
qDebug() << "probono: AutoSelectFirstFilter triggered";
QModelIndex i = l->model()->index(0,0);
if(i.isValid()) {
l->selectionModel()->select(i, QItemSelectionModel::Select); // FIXME: This does not work yet. Why?
}
}
return QObject::eventFilter(obj, e);
}
};
Maybe @keshavbhatt has an idea why this is not working?
Hi, I have figured out a way to achieve this :
Check this out if it helps.
#include <QCompleter>
#include <QDebug>
#include <QAbstractItemView>
#include <QKeyEvent>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStringList completionData = {"mpv","olivia","olivia2","vlc"};
QCompleter * completer = new QCompleter(completionData,ui->lineEdit);
completer->popup()->installEventFilter(this);
ui->lineEdit->setCompleter(completer);
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if(watched == ui->lineEdit->completer()->popup() && event->type() == QEvent::Show){
QCompleter *completer = ui->lineEdit->completer();
if(completer->completionCount() == 1){
completer->setCurrentRow(0); // this is not changing the currenrow selection
//so here's a work around to achieve the behaviour
QKeyEvent *event = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
QCoreApplication::postEvent (ui->lineEdit->completer()->popup(), event);
}
}
return QMainWindow::eventFilter(watched,event);
}
I suggest you to have the behavior like: When user input something in lineEdit the result completer pops up -> if the user hit Enter key with nothing selected -> first item action should be executed.(Similar to unity7 dash search);
For this, you need a little tweaking in the above code. Ping if you need any help.
@keshavbhatt trying it out right now. Thank you so much for your help again!
I only seem to get one initial QEvent::Show
, and thereafter for each additional keystroke only QEvent::KeyPress
. Hence I seemingly need to use QEvent::KeyPress
instead of QEvent::Show
.
But then, once I send the QEvent::KeyPress
, then I get a QEvent::KeyPress
event back, which in turn ends in an endless loop...
@keshavbhatt As you can see, I get QEvent::Show
only when I type the first character, but not on the subsequent ones. But at the time when I press the first character, there is clearly more than one choice left.
Code:
I will look into this.
Got it to work. Thank you very much @keshavbhatt
Finally cracked it:
// completer->setCurrentRow(0); // This is not changing the current row selection, but the following does
QListView* l = static_cast<QListView*>(completer->popup());
QModelIndex idx = completer->completionModel()->index(0, 0,QModelIndex());
l->setCurrentIndex(idx);
Automatically select the first search result once there is only one result left, so that one can just press Enter.
How it is right now:
How it should be:
https://stackoverflow.com/q/17782277 did not work for me so far:
https://github.com/helloSystem/Menu/blob/aaf84275a9eb1c3aed494bc30b8665b2afe9440c/src/appmenuwidget.cpp#L177-L180