QCompleter和Tab键

4
我正在尝试在按下tab键时实现自动完成,以获取所有可能的第一个自动完成。

但是,在基于QWidget的主窗口中,按下tab键会使得QLineEdit失去焦点,之后自动完成弹出框也会隐藏。

有没有一种方法可以解决这个问题?


你解决了吗?我也在尝试实现同样的功能:使用QLineEdit的子类,我成功地拦截了Tab键,但是高亮显示第一个可用的完成选项对我来说仍然无法正常工作。 - AkiRoss
1
@AkiRoss 从未尝试过,但你可以看一下QtCreator的代码。文件选择对话框似乎具有选项卡完成功能。 - daisy
3个回答

3
哎呀,我花了一些时间才想通这个问题 :) 我尝试过多次解决这个问题,但是总是放弃。现在,我挖掘了足够的信息来找到答案。
OP,请原谅我,因为代码是用Python编写的,但是也适用于C++。
基本上,我的问题是“如何选择QCompleter中的条目”;我之前没有注意到,但是答案在方法中。QCompleter使用一个模型和一个视图,其中包含要显示的内容。
您可以按照自己的意愿更改当前行,然后获取该行在模型中的索引,然后在弹出窗口中选择它。
在我的代码中,我继承了QLineEdit,创建了一个tabPressed信号,每次按下Tab键时都会发出。然后,将此信号连接到同一类的一个方法,该方法执行以下操作:
  1. 获取当前索引;
  2. 选择弹出窗口中的索引;
  3. 进入下一行。
作为实现,这非常简单,但对于我当前的目的来说已经足够了。这是骨架(仅针对“tab”部分,缺少模型和其他所有内容)。
class MyLineEdit(QLineEdit):
    tabPressed = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self._compl = QCompleter()
        self.tabPressed.connect(self.next_completion)

    def next_completion(self):
        index = self._compl.currentIndex()
        self._compl.popup().setCurrentIndex(index)
        start = self._compl.currentRow()
        if not self._compl.setCurrentRow(start + 1):
            self._compl.setCurrentRow(0)

    def event(self, event):
        if event.type() == QEvent.KeyPress and event.key() == Qt.Key_Tab:
            self.tabPressed.emit()
            return True
        return super().event(event)

你可能需要调整/修复一些东西,但这是基本的想法。
编辑:
详见 http://www.qtcentre.org/threads/23518-How-to-change-completion-rule-of-QCompleter 有一个小问题:当按下Return键时,事情不起作用。也许你可以在上面的链接或其中引用的资源中找到解决这个问题的方法。我将在未来几天内解决这个问题并更新此答案。

3

1

可能有更好的解决方案,但我想到的一个方法是将表单上所有其他小部件的焦点策略更改为不包括“tab”焦点的选项。唯一不使用Tab键的选项是Qt :: ClickFocusQt :: NoFocus


仍然存在问题,焦点没有再移动,但是按下 Tab 键后完成对话框立即关闭。 - daisy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接