Ok, since I could not get my button icon to look like the one in the QComboBox I've tried an alternative approach based on QComboBox. Here are the features that I want to have:

1. Items displayed in combo box are predetermined and do not change.
2. have combo box's line edit editable and when text is entered there, have list view popup (with some short delay) and select first item matching text entered
3. have event filter on the list view to behave like regular comboBox (pressing enter - selects item etc)

I have two classes: ChmComboBox and ChmCompleter, where the later is being derived from QListView:

Qt Code:
  1. class ChmCompleter : public QListView
  2. {
  3. Q_OBJECT
  4.  
  5. public:
  6. ChmCompleter(QLineEdit *a_editor, QWidget *a_parent = 0);
  7. ~ChmCompleter();
  8. bool eventFilter(QObject *a_obj, QEvent *a_event);
  9.  
  10. public slots:
  11. void doneCompletion();
  12. void preventSuggest();
  13. void autoSuggest();
  14. void showPopup();
  15.  
  16. private:
  17. QLineEdit *m_editor;
  18. QTimer *m_timer;
  19.  
  20. };
  21.  
  22. class ChmComboBox : public QComboBox
  23. {
  24. Q_OBJECT
  25.  
  26. public:
  27. ChmComboBox(QWidget *a_parent = 0);
  28.  
  29. protected slots:
  30. void doSearch();
  31.  
  32. signals:
  33. void textEntered(const QString &a_s);
  34.  
  35. private:
  36. ChmCompleter *m_completer;
  37.  
  38. };
To copy to clipboard, switch view to plain text mode 

Here is my implementation:

Qt Code:
  1. // ************* ChmCompleter *****************************
  2.  
  3. ChmCompleter::ChmCompleter(QLineEdit *a_editor, QWidget *a_parent)
  4. : QListView(a_parent),m_editor(a_editor)
  5. {
  6. setWindowFlags(Qt::Popup);
  7. setFocusPolicy(Qt::NoFocus);
  8. setFocusProxy(a_editor);
  9. setMouseTracking(true);
  10. installEventFilter(this);
  11.  
  12. m_timer = new QTimer(this);
  13. m_timer->setSingleShot(true);
  14. m_timer->setInterval(500);
  15. connect(m_timer, SIGNAL(timeout()), this, SLOT(autoSuggest()) );
  16. connect(m_editor, SIGNAL(textEdited(QString)), m_timer, SLOT(start()) );
  17. }
  18.  
  19. ChmCompleter::~ChmCompleter()
  20. {
  21. if(m_timer)
  22. delete(m_timer);
  23. }
  24.  
  25. bool ChmCompleter::eventFilter(QObject *a_obj, QEvent *a_event)
  26. {
  27. if(a_obj != this)
  28. return false;
  29.  
  30. if(a_event->type() == QEvent::MouseButtonPress)
  31. {
  32. hide();
  33. m_editor->setFocus();
  34. return true;
  35. }
  36.  
  37. if(a_event->type() == QEvent::KeyPress)
  38. {
  39. bool consumed = false;
  40. int key = static_cast<QKeyEvent*>(a_event)->key();
  41. switch(key)
  42. {
  43. case Qt::Key_Enter:
  44. case Qt::Key_Return:
  45. doneCompletion();
  46. consumed = true;
  47.  
  48. case Qt::Key_Escape:
  49. m_editor->setFocus();
  50. hide();
  51. consumed = true;
  52.  
  53. case Qt::Key_Up:
  54. case Qt::Key_Down:
  55. case Qt::Key_Home:
  56. case Qt::Key_End:
  57. case Qt::Key_PageUp:
  58. case Qt::Key_PageDown:
  59. break;
  60.  
  61. default:
  62. m_editor->setFocus();
  63. m_editor->event(a_event);
  64. hide();
  65. break;
  66. }
  67.  
  68. return consumed;
  69. }
  70.  
  71. return false;
  72. }
  73.  
  74. void ChmCompleter::showPopup()
  75. {
  76. QModelIndex start = model()->index(0, 0);
  77. QModelIndexList mi = model()->match(start, Qt::DisplayRole, m_editor->text(), 1, Qt::MatchStartsWith);
  78. if( mi.count() > 0)
  79. selectionModel()->setCurrentIndex(mi.at(0), QItemSelectionModel::Select);
  80. setFocus();
  81. show();
  82. }
  83.  
  84. void ChmCompleter::doneCompletion()
  85. {
  86. m_timer->stop();
  87. hide();
  88. m_editor->setFocus();
  89. QModelIndex index = selectionModel()->currentIndex();
  90. if(index.isValid())
  91. {
  92. m_editor->setText(model()->data(index).toString());
  93. QMetaObject::invokeMethod(m_editor, "returnPressed");
  94. }
  95. }
  96.  
  97. void ChmCompleter::preventSuggest()
  98. {
  99. m_timer->stop();
  100. }
  101.  
  102. void ChmCompleter::autoSuggest()
  103. {
  104. QString str = m_editor->text();
  105. if(!str.isEmpty())
  106. showPopup();
  107. }
  108.  
  109. // ************* ChmComboBox **************
  110. ChmComboBox::ChmComboBox(QWidget *a_parent)
  111. : QComboBox(a_parent)
  112. {
  113. setEditable(true);
  114. setCompleter(0);
  115. setInsertPolicy(QComboBox::NoInsert);
  116. m_completer = new ChmCompleter(this->lineEdit(), this);
  117. connect(lineEdit(), SIGNAL(returnPressed()), this, SLOT(doSearch()) );
  118. setFocus();
  119. lineEdit()->setPlaceholderText("Type or select Y-variable");
  120.  
  121. QStringListModel *model = new QStringListModel(this);
  122. setModel(model);
  123. setView(m_completer);
  124. m_completer->installEventFilter(m_completer);
  125. m_completer->viewport()->installEventFilter(m_completer);
  126. }
  127.  
  128. void ChmComboBox::doSearch()
  129. {
  130. m_completer->preventSuggest();
  131. if(lineEdit()->text() == lineEdit()->placeholderText())
  132. return;
  133. else if(findText(lineEdit()->text()) >= 0)
  134. emit(currentIndexChanged(lineEdit()->text()));
  135. else
  136. // ATTENTION!!! add popup dialog here
  137. }
To copy to clipboard, switch view to plain text mode 

Now I am having some problems that I can not resolve:

1. List view does not show when I type in line edit. I did verify that ChmCompleter::showPopup() function is called, but calling show() there has no effect whatsoever.

2. Pressing keys when listView is open has no effect and eventFilter is not catching any events.

I would greatly appreciate if anyone could suggest what I need to do to get this code to work correctly. Thanks in advance for any help.