2

This is what my example looks like:

Disable Return

The text area is a QPlainTextEdit() object because I want the text to wrap to the second line. I think this is the best widget choice.

The user will only enter a maximum number of 90 characters in this box so I don't need a large text area.

I want to disable the key press Enter (carriage return). I got it to work but it seems hacky and I don't think it would work cross-platform (ex: Mac).

Surely, there's got to be a better way to prevent a carriage return key event in a QPlainTextEdit object?

My Current Solution Explained

Below, you can see I'm checking if an IndexError occurs because the last_value throws an IndexError when there's nothing in the QPlainTextEdit box. Then, I'm getting the last character and asking if it's equal to a new line. If it is, I'm re-setting the text without that new line and moving the cursor to the end.

    def some_event(self):
        try:
            last_value = self.field.toPlainText()[-1]
            if last_value == '\n':
                print('You Pressed Enter!', repr(last_value))
                self.field.setPlainText(self.field.toPlainText()[:-1])
                self.field.moveCursor(QTextCursor.End)
        except IndexError:
            print('Index Error occurred')
            pass

Full Code Minimal Working Example:

from PyQt5.QtWidgets import (QWidget, QMainWindow, QGridLayout, QPushButton,
                             QApplication, QPlainTextEdit, QLabel)
from PyQt5.QtGui import QTextCursor

class BasicWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.initWindow()

    def initWindow(self):
        self.setGeometry(400, 300, 400, 100)

        self.grid = QGridLayout()

        self.label = QLabel('Description Line 1')
        self.grid.addWidget(self.label, 0, 0)

        self.field = QPlainTextEdit()
        self.field.setMaximumHeight(40)

        self.field.textChanged.connect(self.some_event)

        #TODO how to disable enter/return key events in this field?
        self.grid.addWidget(self.field, 1, 0)

        self.button = QPushButton('Some Button')
        self.grid.addWidget(self.button)

        self.centralWidget = QWidget()
        self.centralWidget.setLayout(self.grid)
        self.setCentralWidget(self.centralWidget)

    def some_event(self):
        try:
            last_value = self.field.toPlainText()[-1]
            if last_value == '\n':
                print('You Pressed Enter!', repr(last_value))
                self.field.setPlainText(self.field.toPlainText()[:-1])
                self.field.moveCursor(QTextCursor.End)
        except IndexError:
            print('Index Error occurred')
            pass

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = BasicWindow()
    window.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Jarad
  • 17,409
  • 19
  • 95
  • 154

1 Answers1

3

One option is to override the keyPressEvent method of the QPlainTextEdit:

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QTextCursor
from PyQt5.QtWidgets import (QWidget, QMainWindow, QGridLayout, QPushButton,
                             QApplication, QPlainTextEdit, QLabel)


class PlainTextEdit(QPlainTextEdit):
    def keyPressEvent(self, event):
        if event.key() in (Qt.Key_Return, Qt.Key_Enter):
            return
        super().keyPressEvent(event)


class BasicWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initWindow()

    def initWindow(self):
        self.setGeometry(400, 300, 400, 100)
        self.label = QLabel("Description Line 1")
        self.field = PlainTextEdit()  
        self.field.setMaximumHeight(40)   
        self.button = QPushButton("Some Button")

        self.centralWidget = QWidget()
        grid = QGridLayout(self.centralWidget)
        grid.addWidget(self.label, 0, 0)
        grid.addWidget(self.field, 1, 0)
        grid.addWidget(self.button)
        self.setCentralWidget(self.centralWidget)


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    window = BasicWindow()
    window.show()
    sys.exit(app.exec_())

Another option that implements the same logic is to use an eventFilter().

from PyQt5.QtCore import QEvent, Qt
from PyQt5.QtGui import QTextCursor
from PyQt5.QtWidgets import (QWidget, QMainWindow, QGridLayout, QPushButton,
                             QApplication, QPlainTextEdit, QLabel)

class BasicWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initWindow()

    def initWindow(self):
        self.setGeometry(400, 300, 400, 100)
        self.label = QLabel("Description Line 1")
        self.field = QPlainTextEdit()  
        self.field.setMaximumHeight(40)   
        self.button = QPushButton("Some Button")

        self.field.installEventFilter(self)

        self.centralWidget = QWidget()
        grid = QGridLayout(self.centralWidget)
        grid.addWidget(self.label, 0, 0)
        grid.addWidget(self.field, 1, 0)
        grid.addWidget(self.button)
        self.setCentralWidget(self.centralWidget)

    def eventFilter(self, obj, event):
        if obj is self.field and event.type() == QEvent.KeyPress:
            if event.key() in (Qt.Key_Return, Qt.Key_Enter):
                return True
        return super().eventFilter(obj, event)


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    window = BasicWindow()
    window.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241