【问题标题】:How can I know when the Enter key was pressed on QTextEdit我怎么知道什么时候在 QTextEdit 上按下了 Enter 键
【发布时间】:2021-01-12 02:28:41
【问题描述】:

我正在使用 PyQt5 在 Python 上为客户端编写 Chat gui。 我有一个 QTextEdit,客户端可以在其中写入消息。 当焦点位于 QTextEdit 上时,我不知道何时按下“Enter”键。

我尝试使用 installEventFilter 函数,但它检测到除 QTextEdit 之外的所有其他小部件上都按下了键。 我能做些什么来解决这个问题?

def initUI(self):
   # ...
    self.text_box = QtWidgets.QTextEdit(self)
    self.installEventFilter(self)
    # ...

def keyPressEvent(self, qKeyEvent):
    print(qKeyEvent.key())
    if qKeyEvent.key() == Qt.Key_Return:
        if self.text_box.hasFocus():
            print('Enter pressed')

【问题讨论】:

    标签: python pyqt pyqt5 qtextedit


    【解决方案1】:

    当您覆盖 keyPressEvent 时,您正在侦听窗口的事件,而是将 eventFilter 安装到 QTextEdit,而不是像您在代码中所做的那样安装到窗口,并检查作为参数传递的对象是否是 QTextEdit:

    def initUI(self):
        # ...
        self.text_box = QtWidgets.QTextEdit(self)
        self.text_box.installEventFilter(self)
        # ...
    
    def eventFilter(self, obj, event):
        if event.type() == QtCore.QEvent.KeyPress and obj is self.text_box:
            if event.key() == QtCore.Qt.Key_Return and self.text_box.hasFocus():
                print('Enter pressed')
        return super().eventFilter(obj, event)
    

    【讨论】:

    • 非常感谢。我可以问另一件事吗?如何将 QTextEdit 中的光标返回到 QTextEdit 的开头(在按下回车键后向下一行),我这样做了,所以每次客户端按下回车键时,它都会删除 text_box 中的文本。但它仍然保持文本光标向下一行。
    • @DanielSegal 创建另一个问题并提供minimal reproducible example 以便可能的解决方案可以指示您的代码和解决方案可能存在的错误。
    • @DanielSegal 我刚刚发布了一个解决此问题的答案
    • @Tillus 请阅读How to AskHow to Answer,因此您不能通过评论向您的帖子添加更多要求,所以我告诉 OP 创建一个新帖子,如果您回答它(如您已经完成了),那么您正在宣传此类不当行为。我会报告你的答案被删除
    • 我读了这个问题,我很确定我改进了答案。大多数具有该用例的人在过滤输入输入时不希望有新行。所以我真的不明白这里的“伤害”,也许更多的细节会有所帮助。
    【解决方案2】:

    如果您确定使用 QTextEdit,@eyllanesc 的答案非常好。

    如果您可以摆脱 QLineEdit 及其限制,您可以使用returnPressed() 信号。 QLineEdit 的最大缺点是您仅限于一行文本。并且没有自动换行。但优点是您不必弄乱 eventFilters 或过多考虑 keyPress 信号如何通过应用程序中的所有小部件。

    这是一个从一个 QLineEdit 复制到另一个的最小示例:

    import sys
    
    from PyQt5.QtWidgets import * 
    
    
    class PrintWindow(QMainWindow):
    
        def __init__(self):
            super().__init__()
            self.left=50
            self.top=50
            self.width=300
            self.height=300
            self.initUI()
    
        def initUI(self):
    
            self.setGeometry(self.left,self.top,self.width,self.height)
    
            self.line_edit1 = QLineEdit(self)
            self.line_edit1.move(50, 50)
            self.line_edit1.returnPressed.connect(self.on_line_edit1_returnPressed)
    
            self.line_edit2 = QLineEdit(self)
            self.line_edit2.move(50, 100)
    
            self.show()
    
        def on_line_edit1_returnPressed(self):
            self.line_edit2.setText(self.line_edit1.text())
    
    if __name__ == '__main__':
    
        app = QApplication(sys.argv)
        window = PrintWindow()
        sys.exit(app.exec_())
    

    在这个例子中,我手动连接到第 22 行的信号 (self.line_edit1.returnPressed.connect)。如果你使用的是 ui 文件,这个连接可以省略,你的程序会自动调用 on__returnPressed 方法。

    【讨论】:

      【解决方案3】:

      当您覆盖 keyPressEvent 时,您正在侦听窗口的事件,而是将 eventFilter 安装到 QTextEdit,而不是像您在代码中所做的那样安装到窗口,并检查作为参数传递的对象是否是 QTextEdit:

      def initUI(self):
          # ...
          self.text_box = QtWidgets.QTextEdit(self)
          self.text_box.installEventFilter(self)
          # ...
      
      def eventFilter(self, obj, event):
          if event.type() == QtCore.QEvent.KeyPress and obj is self.text_box:
              if event.key() == QtCore.Qt.Key_Return and self.text_box.hasFocus():
                  print('Enter pressed')
                  return True
          return False
      

      这是基于@eyllanesc 的回答和@Daniel Segal 面临的问题。将正确的返回值添加到eventFilter 即可解决问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-24
        • 2016-08-07
        • 1970-01-01
        • 2014-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多