Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any standard way to create drop-down menu from QLineEdit without QCompleter?

Is there any standard way to create drop-down menu from QLineEdit without QCompleter? For example, using QMenu or creating own class. Or there are any other existing widgets?

Or maybe I should use QAbstractItemModel for QCompleter? I've thought about it, but I don't really understand this QAbstractItemModel. If you have experience about creating menu in this way, please also help me.

So I need a common type of drop-down menu: menu with lines, everyone of which includes icon (QPixmap) and text (QLabel) in itself. It's like in Opera or Chrome browser in address input line, like the right part of Apple Spotlight etc.

like image 578
Ivan Akulov Avatar asked Oct 07 '22 22:10

Ivan Akulov


1 Answers

It's not possible with QMenu because it catch focus when showed and hides when loses focus. However, it's possible to use QListWidget (or any other regular widget) for this. I developed some working example for the proof of concept. It's default Qt Widget project with QMainWindow as main window. You need to add QLineEdit with name "lineEdit" into it and create slot for textChanged signa. Here's the code:

MainWindow.h:

class MainWindow : public QMainWindow {
  Q_OBJECT  
public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();  
private slots:
  void on_lineEdit_textChanged(const QString &arg1);
private:
  Ui::MainWindow *ui;
  QListWidget* list;
};

MainWindow.cpp:

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow),
  list(new QListWidget)
{
  ui->setupUi(this);
  list->setWindowFlags(Qt::WindowFlags(
    Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint));
  list->setAttribute(Qt::WA_ShowWithoutActivating);
}

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

void MainWindow::on_lineEdit_textChanged(const QString &arg1) {
  if (ui->lineEdit->text().isEmpty()) {
    list->hide();
    return;
  }
  list->clear();
  list->addItem(ui->lineEdit->text());
  list->addItem(tr("Google: ") + ui->lineEdit->text());
  list->move(ui->lineEdit->mapToGlobal(QPoint(0, ui->lineEdit->height())));
  if (!list->isVisible()) list->show();
}

There are several problems: you should hide menu when line edit loses focus or user move window, you can't set focus on the menu using down arrow button from line edit, etc. But I believe all these issues can be solved easily.

like image 61
Pavel Strakhov Avatar answered Oct 12 '22 09:10

Pavel Strakhov