PyQt QComboBox.setEditText 留下输入的文本selected/highlighted;如何取消突出显示?

PyQt QComboBox.setEditText leaves the entered text selected/highlighted; how to unhighlight?

UPDATE3 - 有保留地解决了, 请在下面查看我的解决方案;由于问题的原因尚不清楚,并且我不知道解决方案有多稳健,因此将其打开。


UPDATE1:这是简短的版本。

目前,在 QComboBox 上的 .setEditText 之后,我得到了这个:

因此您输入的下一个内容将覆盖 'Team '。

但所需的效果是这样的(未突出显示/未选中),这样您输入的下一个内容将附加到 'Team ' 而不是覆盖它:

感谢您的帮助。乱七八糟的细节如下,原文为post:

(这都是 PyQt 5.4)

更新2: 显然 python 认为实际上没有选择任何东西:

    self.entryForm.ui.teamField.lineEdit().setText("Team ")
    print("selected text:"+self.entryForm.ui.teamField.lineEdit().selectedText())

打印 "selected text:",仅此而已。为确保它正常工作:

self.entryForm.ui.teamField.lineEdit().setText("Team ")
self.entryForm.ui.teamField.lineEdit().setSelection(0,4)
print("selected text:"+self.entryForm.ui.teamField.lineEdit().selectedText())

打印"selected text:Team"

这可能就是为什么许多影响选择的方法没有按预期工作(.deselect()、.setSelection(5,5) 等,甚至其他一些方法会产生意外行为,即cursorForward(False,1) 或 cursorBackward(False,1) 等。

原post:

这是用于无线电日志 GUI,因此键盘交互必须最少且直观。 openNewEntryForm(下图)在主应用程序 GUI window:

上作为一个按钮调用
self.ui.pushButton.clicked.connect(self.openNewEntryDialog)

也可以在相同的情况下使用 keyPressEvent 调用它 class:

def keyPressEvent(self,event):
    if type(event)==QKeyEvent:
        print("QKeyEvent:"+str(event.key()))
        if event.key()==Qt.Key_T:
            self.openNewEntryDialog('t')
        event.accept()
    else:
        event.ignore()

这是有问题的方法:

def openNewEntryDialog(self,key=None):
    self.entryDialog=newEntryDialog()
    if key=='t':
        self.entryDialog.ui.to_fromField.setCurrentIndex(1)
        self.entryDialog.ui.teamField.setFocus()
        self.entryDialog.ui.teamField.setEditText("Team ")

    if self.entryDialog.exec_():
        self.newEntry(self.entryDialog.getValues()) # adds the log entry

所以,预期的按键顺序是(来自主应用程序 GUI window):

按一下键盘 't' 将打开 entryForm,将 to_fromField 设置为索引 1(恰好是 "TO"),将焦点放在 teamField(也是一个 QComboBox ), 将其文本设置为 "Team " 并自行设置,以便下一次按键将显示为 teamField."Team " 之后的文本。

因此,再次从主应用程序 GUI 开始,计划是键入 't3' 应该打开新条目 window,将 to_fromField 设置为 "TO",并将 teamField 设置为 "Team 3",准备好按 Tab 键移动到 entryForm 中的下一个字段。

问题是 teamField.setEditText("Team ") 调用留下所有文本 highlighted/selected,因此随后的 '3' 按键会将 "Team " 替换为 "3";我正在寻找 unhighlight/unselect "Team " 的方法,但将光标留在该字符串的右侧,以便随后的 '3' 按键将使整个字符串 "Team 3".

想法?提前致谢。

您可以访问组合框的行编辑,然后删除选择:

    self.entryDialog.ui.teamField.setEditText("Team ")
    self.entryDialog.ui.teamField.lineEdit().deselect()

更新:

上面的代码是正确的,但似乎对话框在显示后初始化其子窗口小部件的焦点处理时会破坏它。如果使用 exec() 打开对话框,它将启动自己的事件循环,并且某些事件(包括焦点事件)将仅在 完全显示后才被处理。这就是为什么在显示对话框之前对子窗口小部件所做的某些更改可能会被忽略的原因。

解决此问题的一种方法是使用单次计时器以确保仅在显示对话框之后尝试更改。

所以在输入对话框中添加一个方法 class 像这样:

    def resetUI(self, key):
        if key == 't':
            self.ui.to_fromField.setCurrentIndex(1)
            self.ui.teamField.setFocus()
            self.ui.teamField.setEditText('Team ')
            QtCore.QTimer.singleShot(0, self.ui.teamField.lineEdit().deselect)

然后像这样使用它:

def openNewEntryDialog(self, key=None):
    self.entryDialog = newEntryDialog()
    self.entryDialog.resetUI(key)
    if self.entryDialog.exec_():
        self.newEntry(self.entryDialog.getValues())

已解决,但有保留,请参阅原始 post 中的 UPDATE3。

因此,在初始文本全部突出显示的情况下,测试表明它实际上并没有认为任何内容都被选中了。这个解决方案只是通过反复试验偶然发现的,摆弄设置和清除焦点,选择文本并尝试取消选择:

def openNewEntryDialog(self,key=None):
        self.entryForm=newEntryDialog()
        if key=='t':
            self.entryForm.ui.to_fromField.setCurrentIndex(1)
            self.entryForm.ui.teamField.lineEdit().setFocus()
            self.entryForm.ui.teamField.lineEdit().setText("Team  ")
            self.entryForm.ui.teamField.lineEdit().setSelection(5,1)

注意 'Team' 之后有两个 space,第二个是有意选择的。然后下一个按键将覆盖第二个space;这基本上是所需的行为。

无论如何,选择方案看起来有点奇怪;一种看待这个问题的方法是,突出显示并不是真正的选择,但是,如果您设置有效的真实选择,那么它将覆盖原来的突出显示 'pseudo-selection'。原始突出显示的行为类似于选择,因为按键将替换突出显示的所有内容,但不像选择,因为选择方法显示没有 'selection',请参阅 UPDATE2 原来post.

谁能帮忙解释一下这种行为?在接受这个巧合的答案之前,我想对它建立更多的信心。

谢谢