【发布时间】:2021-08-11 20:02:46
【问题描述】:
我需要实现自定义完成器,类似于QCompleter,但包含自定义小部件。我一开始就卡住了,我无法让弹出窗口正常工作。在下面的示例中,我将一个完成器(嗯,只是一个普通的小部件)附加到第一行编辑。第二行编辑只是为了测试焦点输入/输出行为。问题是当弹出窗口显示时,它会从行编辑中窃取焦点。但这不是我想要的,我希望能够继续在行编辑中输入。我尝试了以下代码中注释的其他几个选项,但没有一个有效。
#include <QApplication>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget container;
QLineEdit editor;
QLineEdit editor2;
QHBoxLayout layout(&container);
layout.addWidget(&editor);
layout.addWidget(&editor2);
QWidget completer; // or QWidget completer(&editor);?
//completer.setFocusProxy(&editor); // tried this, but it does not help
completer.setWindowFlags(Qt::Popup);
// the following lines are an alternative to Qt::Popup but the window
// does not close automatically, which is a problem
// e.g. when moving or resizing the parent window
//completer.setAttribute(Qt::WA_ShowWithoutActivating);
//completer.setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
QObject::connect(&editor, &QLineEdit::textEdited,
[&] {
completer.resize(editor.width(), 100);
completer.move(editor.mapToGlobal(QPoint(0, editor.height())));
completer.show();
// editor.setFocus(); // does not help either
});
container.show();
return a.exec();
}
如何实现自定义完成器?
更新:从文档中,我读到“弹出小部件是一个特殊的顶级小部件,它设置 Qt::WType_Popup 小部件标志,例如 QMenu 小部件。当应用程序打开弹出小部件时,所有事件都会发送到弹出窗口。在弹出窗口小部件关闭之前,无法访问普通小部件和模式小部件。"
看来,当我打开一个弹出窗口时,它会自动接收事件,因此我必须使用Completer::keyPressEvent 中的QCoreApplication::sendEvent(editor, event); 将事件转发到行编辑。除了行编辑中的光标不可见或不闪烁之外,这似乎工作正常。
【问题讨论】:
-
另一个想法:您可以使用
QCompleter::popup()检索弹出窗口小部件,然后使用Qt::NoFocus应用Widget::setFocusPolicy()。看着这个,我还看到了QWidget::setFocusProxy(),这似乎也值得调查。 -
我不能使用标准的 Qt 完成程序,因为弹出窗口必须继承自
QAsbtractItemView。而且我需要将弹出行为与自定义小部件相结合...