C++ QComboBox编辑行在弹出窗口处于活动状态时编辑
我有一个C++ QComboBox编辑行在弹出窗口处于活动状态时编辑,c++,qt,C++,Qt,我有一个QComboBox里面装满了一些数据。我想编辑组合框的行编辑,当我这样做时,组合框会在我编辑时显示弹出窗口。问题是我失去了行编辑的焦点,一次只能写一封信 这是我在一个琐碎的层面上所做的: ui->comboBox->addItem("This"); ui->comboBox->addItem("is"); ui->comboBox->addItem("a"); ui->comboBox->addItem("comboBox"); ui-&
QComboBox
里面装满了一些数据。我想编辑组合框的行编辑
,当我这样做时,组合框
会在我编辑时显示弹出窗口。问题是我失去了行编辑的焦点,一次只能写一封信
这是我在一个琐碎的层面上所做的:
ui->comboBox->addItem("This");
ui->comboBox->addItem("is");
ui->comboBox->addItem("a");
ui->comboBox->addItem("comboBox");
ui->comboBox->setEditable(true);
connect(ui->comboBox, SIGNAL(currentTextChanged(QString)), this, SLOT(PrintTextLineEdit(QString)));
void MainWindow::PrintTextLineEdit(QString str)
{
ui->comboBox->showPopup();
ui->comboBox->lineEdit()->setFocus();
}
另外,如果我在显示弹出窗口时使用行编辑
上的块信号
,则该弹出窗口无效。有什么建议吗
编辑
看来我需要提供一些额外的细节。当我在currentTextChanged
信号中使用ui->comboBox->showPopUp()
时,我需要能够一次编写一个完整的单词而不会失去焦点
或者简单地说:发出信号并显示弹出窗口后,光标不需要从QLineEdit
中消失。每个组合框都有一个默认的QCompleter
,可以在弹出窗口中显示完成选项。我认为,通过将此completers模式设置为PopupCompletion
,您可以实现您想要的功能
ui->comboBox->completer()->setCompletionMode(QCompleter::PopupCompletion);
在这种情况下,combobox将在键入时显示匹配的选择。如果您想让它列出combobox的所有项目,我认为您应该实现一个自定义的QCompleter,它匹配所有项目,而不管用户类型是什么。每个combobox都有一个默认的QCompleter
,可以在弹出窗口中显示完成选项。我认为,通过将此completers模式设置为PopupCompletion
,您可以实现您想要的功能
ui->comboBox->completer()->setCompletionMode(QCompleter::PopupCompletion);
在这种情况下,combobox将在键入时显示匹配的选择。如果您想让它列出combobox的所有项目,我认为您应该实现一个定制的QCompleter,它匹配所有项目,而不管用户类型是什么。当我查看QCombobox的代码时,我在showPopup代码中看到以下内容:
container->show();
container->updateScrollers();
view()->setFocus(); // <<-- focus command here
view()->scrollTo(view()->currentIndex(),
style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)
? QAbstractItemView::PositionAtCenter
: QAbstractItemView::EnsureVisible);
值得一试。当我查看QCombobox的代码时,我在showPopup代码中看到以下内容:
container->show();
container->updateScrollers();
view()->setFocus(); // <<-- focus command here
view()->scrollTo(view()->currentIndex(),
style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)
? QAbstractItemView::PositionAtCenter
: QAbstractItemView::EnsureVisible);
值得一试。您需要从QComboBox
派生您自己的组合框类,并重写showPopup()
虚拟方法以将焦点返回到行编辑
void CMyComboBox::showPopup()
{
QComboBox::showPopup();
// Put the focus back later, after all pending events are processed.
QTimer::singleShot(0, [this](){ lineEdit()->setFocus(); });
}
作为特例,超时为0的QTimer将尽快超时
因为窗口系统的事件队列中的所有事件都已
已处理
编辑:
这是有效的(虽然人们可以认为它是一个黑客):
CMYCOMBOX类:公共QCOMBOX
{
公众:
CMYCOMBOX(QWidget*父项)
:QComboBox(父级)
{
view()->installEventFilter(此);
}
//事件过滤器将查看关键事件转发到行编辑。
bool事件过滤器(QObject*监视,QEvent*事件)
{
如果(事件->类型()==QEvent::按键)
{
QKeyEvent*keyEvent=静态广播(事件);
QKeyEvent*newEvent=新的QKeyEvent(keyEvent->type(),keyEvent->key(),keyEvent->modifiers(),
keyEvent->text(),keyEvent->isAutoRepeat(),keyEvent->count());
QFocusEvent*focusEvent=新QFocusEvent(QEvent::FocusIn,Qt::OtherFocusReason);
QCoreApplication::postEvent(lineEdit(),focusEvent);
QCoreApplication::postEvent(lineEdit(),newEvent);
}
返回false;
}
};
但就个人而言,我可能会使用一个单独的QMenu
来显示单词列表,而不是组合框的弹出菜单。您需要从QComboBox
派生您自己的组合框类,并覆盖showPopup()
虚拟方法以将焦点返回到行编辑
void CMyComboBox::showPopup()
{
QComboBox::showPopup();
// Put the focus back later, after all pending events are processed.
QTimer::singleShot(0, [this](){ lineEdit()->setFocus(); });
}
作为特例,超时为0的QTimer将尽快超时
因为窗口系统的事件队列中的所有事件都已
已处理
编辑:
这是有效的(虽然人们可以认为它是一个黑客):
CMYCOMBOX类:公共QCOMBOX
{
公众:
CMYCOMBOX(QWidget*父项)
:QComboBox(父级)
{
view()->installEventFilter(此);
}
//事件过滤器将查看关键事件转发到行编辑。
bool事件过滤器(QObject*监视,QEvent*事件)
{
如果(事件->类型()==QEvent::按键)
{
QKeyEvent*keyEvent=静态广播(事件);
QKeyEvent*newEvent=新的QKeyEvent(keyEvent->type(),keyEvent->key(),keyEvent->modifiers(),
keyEvent->text(),keyEvent->isAutoRepeat(),keyEvent->count());
QFocusEvent*focusEvent=新QFocusEvent(QEvent::FocusIn,Qt::OtherFocusReason);
QCoreApplication::postEvent(lineEdit(),focusEvent);
QCoreApplication::postEvent(lineEdit(),newEvent);
}
返回false;
}
};
但就我个人而言,我可能会使用一个单独的QMenu
来显示单词列表,而不是组合框的弹出菜单。您的问题是由抓取键盘造成的。键盘被弹出窗口抓取,因此解决方法很简单,只需使用grabKeyBoard()
将编辑设置为重新标记键盘即可。您的问题是由grabKeyBoard
引起的。键盘被弹出窗口抓取,因此解决方案很简单,只需将编辑设置为重新标记键盘,使用grabKeyBoard()
使用的功能可能是更好/更少的解决方案:
QStringListModel *model; // or another QAbstractItemModel
model->setStringList({"This", "is", "a", "combobox"});
QLineEdit *lineEdit;
lineEdit->setCompleter(new QCompleter(model, lineEdit));
lineEdit->completer()->setFilterMode(Qt::MatchContains); // set filter mode as desired
一旦用户开始编辑行编辑,将显示一个弹出窗口。这种方法的唯一缺点是没有下拉图标来显示所有可能的(未过滤的)项目。使用的功能可能是更好/更少的解决方案:
QStringListModel *model; // or another QAbstractItemModel
model->setStringList({"This", "is", "a", "combobox"});
QLineEdit *lineEdit;
lineEdit->setCompleter(new QCompleter(model, lineEdit));
lineEdit->completer()->setFilterMode(Qt::MatchContains); // set filter mode as desired
一旦用户开始编辑行编辑,将显示一个弹出窗口。这种方法的唯一缺点是没有下拉图标来显示所有可能的(未过滤的)项目。您实际上要实现什么样的行为?某种下拉建议列表?某种过滤器,但没有代理或自定义列表。我的问题是我希望我能键入一个单词wi