TheInitializer
TheInitializer

Reputation: 576

Mystery newline being added to the end of QPlainTextEdit

I'm making a kind of command line simulator using Python 2.7 and PyQt5, and the way it works is every character you type it listens for the key. When you press it it calls self.parse() which does stuff.

When I load up the window it works fine, and the cursor is placed after the prompt (C:\>). When I type in a command, and press enter, the stuff is printed, and a new prompt is printed. Then a newline is printed, and the cursor is placed after that newline.

I don't want this. How can I fix it?

I've tried tons of different things. I've tried plainTextEdit.textCursor().deletePreviousChar(). I've tried using insertPlainText as well as appendPlainText. The same thing happens in each case. It's really frustrating.

The even more frustrating part is I have no idea where in my code the newline is being added. It's probably not in parse or else deletePreviousChar would work. And I can't think where else it would be...

Here's my class:

class CmdLine(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)

        self.ui = uic.loadUi('cmd.ui', self)
        self.ui.show()

        self.plainTextEdit.appendPlainText("C:\\> ")

        self.plainTextEdit.installEventFilter(self)

        self.editable = True
        self.keys = []
        self.lolnope = []

    def eventFilter(self, widget, event):
        if event.type() == QtCore.QEvent.KeyPress:
            print event.text()
            if self.editable:
                if event.key() == QtCore.Qt.Key_Return:
                    self.parse()   
                else:
                    self.keys += event.text()
                return QtWidgets.QMainWindow.eventFilter(self, widget, event)
            else:
                self.lolnope += event.text()
                return True
        else:
            return QtWidgets.QMainWindow.eventFilter(self, widget, event)

    def parse(self):
        self.editable = False
        self.plainTextEdit.moveCursor(QtGui.QTextCursor.End)
        s = ''.join(self.keys)
        # parse input and do things
        self.keys = []
        self.editable = True
        self.plainTextEdit.moveCursor(QtGui.QTextCursor.End)
        self.plainTextEdit.appendPlainText("C:\\> ") 
        self.plainTextEdit.textCursor().deletePreviousChar();

    def __del__(self):
        with open('lolnope.txt', 'w') as f:
            f.write(''.join(self.lolnope))

Could anyone help?

Upvotes: 1

Views: 1483

Answers (1)

ekhumoro
ekhumoro

Reputation: 120598

You need to bypass the normal handling of return/enter, and then use insertPlainText to control how newlines are entered:

class CmdLine(QtWidgets.QMainWindow):
    def __init__(self):
        super(CmdLine, self).__init__()
        ...
        self.plainTextEdit.insertPlainText("C:\\> ")

    def eventFilter(self, widget, event):
        if event.type() == QtCore.QEvent.KeyPress:
            print event.text()
            if self.editable:
                if (event.key() == QtCore.Qt.Key_Return or
                    event.key() == QtCore.Qt.Key_Enter):
                    self.parse()
                    # bypass default handling
                    return True
                else:
                    self.keys += event.text()
            else:
                self.lolnope += event.text()
                return True
        return super(CmdLine, self).eventFilter(widget, event)

    def parse(self):
        ...
        # terminate current line and start a new one
        self.plainTextEdit.insertPlainText("\nC:\\> ")

Upvotes: 1

Related Questions