我有QComboBox
填充了一些数据。我希望修改lineEdit
的{{1}},当我这样做时,我会在编辑时弹出comboBox
。问题是我失去了comboBox
的焦点,我一次只能写一个字母。
这就是我在一个微不足道的层面所做的事情:
lineEdit
此外,如果我在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();
}
上使用blockSignal
,而我显示弹出窗口则无用。有什么建议吗?
修改
我似乎需要提供一些额外的细节。当我在lineEdit
信号中使用ui->comboBox->showPopUp()
时,我需要能够一次写出整个单词而不会失去焦点。
或者说简单:在发出信号并显示popUp后,光标不需要从currentTextChanged
消失。
答案 0 :(得分:3)
每个组合框都有一个默认的QCompleter
,可以在弹出窗口中显示完成选项。我认为通过将此完成模式设置为PopupCompletion
可以达到您想要的效果。
ui->comboBox->completer()->setCompletionMode(QCompleter::PopupCompletion);
在这种情况下,组合框将在键入时显示匹配的选择。如果您希望它列出所有组合框,我认为您应该实现一个匹配所有项目的自定义QCompleter,无论用户类型是什么。
答案 1 :(得分:1)
您需要从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将会很快超时 因为窗口系统事件队列中的所有事件都已存在 处理。
修改强>
这有效(尽管人们可以将其视为黑客):
class CMyComboBox : public QComboBox
{
public:
CMyComboBox(QWidget* parent)
: QComboBox(parent)
{
view()->installEventFilter(this);
}
// Event filter forwards view key events to the line edit.
bool eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
QKeyEvent* newEvent = new QKeyEvent(keyEvent->type(), keyEvent->key(), keyEvent->modifiers(),
keyEvent->text(), keyEvent->isAutoRepeat(), keyEvent->count());
QFocusEvent* focusEvent = new QFocusEvent(QEvent::FocusIn, Qt::OtherFocusReason);
QCoreApplication::postEvent(lineEdit(), focusEvent);
QCoreApplication::postEvent(lineEdit(), newEvent);
}
return false;
}
};
但就个人而言,我可能会使用单独的QMenu
来显示单词列表,而不是组合框的弹出菜单。
答案 2 :(得分:1)
您的问题是由 grabKeyboard
引起的。键盘被弹出窗口抓取,所以解决方案很简单,只需将编辑设置为重新抓取键盘,使用 grabKeyBoard()
答案 3 :(得分:0)
当我查看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);
所以,如果您执行以下操作(此处未测试),您可能会获得所需的结果:
ui->comboBox->addItem("This");
ui->comboBox->addItem("is");
ui->comboBox->addItem("a");
ui->comboBox->addItem("comboBox");
ui->comboBox->setEditable(true);
ui->comboBox->view()->setFocusPolicy(Qt::FocusPolicy::NoFocus); // don't allow focusing of the view of the popup
connect(ui->comboBox, SIGNAL(currentTextChanged(QString)), this, SLOT(PrintTextLineEdit(QString)));
void MainWindow::PrintTextLineEdit(QString str)
{
ui->comboBox->showPopup();
ui->comboBox->lineEdit()->setFocus();
}
值得一试。
答案 4 :(得分:0)
使用 QCompleter
的 QLineEdit
功能可能是一个更好/更简单的解决方案:
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
一旦用户开始编辑行编辑,就会显示一个弹出窗口。这种方法的唯一缺点是没有下拉图标来显示所有可能的(未过滤的)项目。