I customized a dialog that contains a QComboBox control m_box
and a QListWidget control m_lst
. The m_box
supports search matching. If an item from the dropdown list of m_box
is selected by directly clicking with the mouse, the cursor will not be displayed in m_box
, as shown in the example below.
If an item from m_box
is selected using the search matching method with the up and down keys and the Enter key, the cursor will also not be displayed in m_box
, as shown in the example below.
However, if matching items are displayed through search matching and an item from the dropdown list is selected with the mouse, the cursor will then be displayed in m_box
, as shown in the example below.
I hope for consistent behavior across all three methods: as long as the selected item exists in the candidate items of m_box
, the cursor should not be displayed in m_box
, unless the mouse is clicked on m_box
, at which point the cursor should appear. Here’s a minimal reproducible example:
#include <QApplication>
#include <QDialog>
#include <QComboBox>
#include <QListWidget>
#include <QCompleter>
#include <QStringList>
#include <QVBoxLayout>
#include <QDebug>
class CustomDialog : public QDialog
{
Q_OBJECT
public:
CustomDialog(QWidget* parent = nullptr) : QDialog(parent)
{
QStringList items;
items << "item1" << "item2";
m_box = new QComboBox(this);
m_box->setEditable(true);
m_box->addItems(items);
QCompleter* completer = new QCompleter(items, m_box);
completer->setFilterMode(Qt::MatchContains);
m_box->setCompleter(completer);
m_lst = new QListWidget(this);
m_lst->addItems(items);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(m_box);
layout->addWidget(m_lst);
connect(m_box, SIGNAL(activated(int)), this, SLOT(onSelChangedBox(int)));
}
public slots:
void onSelChangedBox(int iSel);
private:
QComboBox* m_box;
QListWidget* m_lst;
};
void CustomDialog::onSelChangedBox(int iSel)
{
qDebug() << "clear focus of m_box";
m_lst->setFocus();
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
CustomDialog dlg;
dlg.setFixedSize(300, 200);
dlg.show();
return a.exec();
}
#include "main.moc"
Note: If a second QComboBox is added and the item is selected using the third method, then clicking on the second QComboBox will result in two cursors appearing. In fact, at this point, the focus is no longer on the first QComboBox, but the cursor is still displayed. The code and example are as follows:
#include <QApplication>
#include <QDialog>
#include <QComboBox>
#include <QListWidget>
#include <QCompleter>
#include <QStringList>
#include <QVBoxLayout>
#include <QDebug>
class CustomDialog : public QDialog
{
Q_OBJECT
public:
CustomDialog(QWidget* parent = nullptr) : QDialog(parent)
{
QStringList items;
items << "item1" << "item2";
m_box1 = new QComboBox(this);
m_box1->setEditable(true);
m_box1->addItems(items);
QCompleter* completer1 = new QCompleter(items, m_box1);
completer1->setFilterMode(Qt::MatchContains);
m_box1->setCompleter(completer1);
m_box2 = new QComboBox(this);
m_box2->setEditable(true);
m_box2->addItems(items);
QCompleter* completer2 = new QCompleter(items, m_box2);
completer2->setFilterMode(Qt::MatchContains);
m_box2->setCompleter(completer2);
m_lst = new QListWidget(this);
m_lst->addItems(items);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(m_box1);
layout->addWidget(m_box2);
layout->addWidget(m_lst);
connect(m_box1, SIGNAL(activated(int)), this, SLOT(onSelChangedBox(int)));
connect(m_box2, SIGNAL(activated(int)), this, SLOT(onSelChangedBox(int)));
}
public slots:
void onSelChangedBox(int iSel);
private:
QComboBox* m_box1;
QComboBox* m_box2;
QListWidget* m_lst;
};
void CustomDialog::onSelChangedBox(int iSel)
{
qDebug() << "clear focus of m_box";
m_lst->setFocus();
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
CustomDialog dlg;
dlg.setFixedSize(500, 500);
dlg.show();
return a.exec();
}
#include "main.moc"
activated
signal is actually emitted in all the cases listed above (a simple qDebug message in the connected function would suffice). Then: if the signal is emitted in all cases, it may be a problem related to event handling (possibly due to the mouse release received after clicking on an item). But I'm not sure that's the case, and the style may not emitactivated
in some cases (some platforms don't do it on single click).clearFocus()
on one widget followed bysetFocus()
on another makes the former quite pointless, as the latter will automatically clear the focus on the first widget, since only one widget can only have focus.m_box->clearFocus()
has been removed from the slot function andqDebug
has been added.setFocus()
with a simpleQTimer::singleShot()
? Eventually connected to a function that also callsQCoreApplication::processEvents()
before setting the focus? What about usingsetFocus()
with an appropriateFocusReason
?