【问题标题】:PyQt QComboBox.setEditText leaves the entered text selected/highlighted; how to unhighlight?PyQt QComboBox.setEditText 使输入的文本保持选中/突出显示;如何取消突出显示?
【发布时间】:2015-03-07 12:09:31
【问题描述】:

UPDATE3 - 通过保留解决,请在下面查看我的解决方案;将其打开,因为问题的原因尚不清楚,而且我不知道解决方案有多强大。


UPDATE1:这是简短的版本。

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

所以您输入的下一个内容将覆盖“团队”。

但是想要的效果是这样(未突出显示/未选择),因此您输入的下一个内容将附加到“团队”而不是覆盖它:

感谢您的帮助。乱七八糟的细节如下,这是原帖:

(这都是 PyQt 5.4)

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

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

打印“选定的文本:”,仅此而已。为确保其正常工作:

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

打印“选定的文本:团队”

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

原帖:

这是用于无线电日志 GUI,因此键盘交互必须最少且直观。 openNewEntryForm(下)作为一个插槽从主应用程序 GUI 窗口上的按钮调用:

self.ui.pushButton.clicked.connect(self.openNewEntryDialog)

也可以在同一个类中使用 keyPressEvent 调用:

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 窗口):

按一次键盘“t”将打开 entryForm,将 to_fromField 设置为索引 1(恰好是“TO”),将焦点放在 teamField(也是一个 QComboBox),将其文本设置为“Team”和设置自己,以便下一个按键将显示为 teamField 中“团队”之后的文本。

所以,再次从主应用程序 GUI 开始,计划是键入“t3”应该打开新的输入窗口,将 to_fromField 设置为“TO”,并将 teamField 设置为“Team 3”,准备好按键的 tab 键移动到 entryForm 中的下一个字段。

问题在于teamField.setEditText("Team ") 调用会突出显示/选中所有文本,因此随后按下'3' 会将"Team " 替换为"3";我正在寻找一种方法来取消突出显示/取消选择“团队”,但让光标在该字符串的右侧保持活动状态,以便随后按下'3' 将使整个字符串变为"Team 3"

想法?提前致谢。

【问题讨论】:

    标签: user-interface pyqt qcombobox


    【解决方案1】:

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

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

    更新

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

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

    所以向入口对话框类添加一个方法,如下所示:

        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())
    

    【讨论】:

    • 这似乎不起作用。感谢您在使用 lineEdit() 方面的领导,但似乎很多 QLineEdit 类方法的行为不如预期。只要您给它一个或多个字符的范围, setSelection 似乎就可以工作; home(False) 和 end(False) 和 deselect() 都会突出显示/选中文本。我会继续尝试 lineEdit 对象的各种方法。
    • 很有趣,谢谢。那么,您是否认为我偶然发现的解决方案仍然受制于竞争条件,因此不够稳健?
    • @TomGrundy。很难说:您必须跟踪 Qt 源代码中的代码才能准确了解发生了什么以及以什么顺序发生。但是,我会说您当前的解决方案并没有真正解决原始问题,因为它没有完全清除选择。它还依赖于输入文本的特定知识(例如其长度),因此不是通用解决方案。
    • 嗯 - 在这两个方面都非常正确。无论如何,感谢您的解决方案以及导致其他偶然解决方案的线索。
    【解决方案2】:

    已解决,请参阅原帖中的 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)
    

    请注意,“团队”后面有两个空格,第二个空格是故意选择的。然后下一个按键将覆盖第二个空格;这基本上是期望的行为。

    无论如何,选择方案看起来很奇怪;看待这一点的一种方法是,突出显示并不是真正的选择,但是,如果您设置了有效的真实选择,那么它将覆盖原始突出显示的“伪选择”。原始突出显示的行为类似于一个选择,因为按键将替换所有突出显示的内容,但与选择不同,因为选择方法显示没有“选择”,请参阅原始帖子中的 UPDATE2 .

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

    谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-27
      相关资源
      最近更新 更多