Solved When inserting 4 spaces or a tab to QPlainTextEdit, i can't delete them
-
Whenever I do
this->insertPlainText(" ");
then the spaces that were added, I can't delete them.But when I do the same thing in python, using PyQt5 like this
self.insertPlainText(" ")
Then i can delete the 4 spaces that were inserted.Why is it like this?
-
Hi
You mean the spaces stay when you press delete button or in
what way, cannot delete ?
It should be the same between python or c++. it calls same function in Qt.So maybe its some sort of unicode thing. I tried test on windows, but
it deleted fine.So on what Qt version and platform do you see this ?
-
Alright, maybe it is something to do with my code then, here is my Plaintextedit class that subclasses qplaintextedit:
#include <QFont> #include <QDebug> #include <iostream> PlainTextEdit::PlainTextEdit(QWidget *parent) { font = new QFont; font->setFamily("Consolas"); font->setPointSize(12); replace_tabs = 4; key_list = {16777217, 16777219, 16777220}; this->setTabStopWidth(40); this->createStandardContextMenu(); this->setWordWrapMode(QTextOption::NoWrap); } void PlainTextEdit::move_cursor_back() { QTextCursor text_cursor = this->textCursor(); int text_cursor_pos = text_cursor.position(); text_cursor.setPosition(text_cursor_pos -1); this->setTextCursor(text_cursor); } void PlainTextEdit::keyPressEvent(QKeyEvent *e) { QTextCursor text_cursor = this->textCursor(); int key = e->key(); if (key == Qt::Key_QuoteDbl) { this->insertPlainText("\""); move_cursor_back(); } if (e->modifiers() == Qt::ControlModifier && e->key() == 61) { this->font->setPointSize(font->pointSize() + 1); this->setFont(*font); } if (e->modifiers() == Qt::ControlModifier && e->key() == 45) { this->font->setPointSize(font->pointSize() - 1); this->setFont(*font); } if (key == 39) { this->insertPlainText("'"); move_cursor_back(); } if (key == Qt::Key_BraceLeft) { this->insertPlainText("}"); move_cursor_back(); } if (key == Qt::Key_BracketLeft) { this->insertPlainText("]"); move_cursor_back(); } if (key == Qt::Key_ParenLeft) { this->insertPlainText(")"); move_cursor_back(); } if (!key_list.contains(key)) { QPlainTextEdit::keyPressEvent(e); return; } // e->accept(); if (key == 16777217 && replace_tabs) { int amount = 4 - this->textCursor().positionInBlock() % 4; QString str = " "; this->insertPlainText(str.repeated(amount)); } else if (key == 16777219 && this->textCursor().selectionStart() == this->textCursor().selectionEnd() && replace_tabs && this->textCursor().positionInBlock()) { int position = this->textCursor().positionInBlock(); int end = this->textCursor().position(); int start = end - (position % 4); if (start == end && position >= 4) { start -= 4; } QString string = this->toPlainText().mid(start, end); QString stripped_string = string.trimmed(); if (!stripped_string.length()) { for (int i; i < end - start; i++) { this->textCursor().deletePreviousChar(); } } else { QPlainTextEdit::keyPressEvent(e); } } else if (key == 16777220) { int end = this->textCursor().position(); int start = end - this->textCursor().positionInBlock(); QString line = this->toPlainText().mid(start, end); int indentation = line.length() - line.trimmed().length(); QString chars = "\t"; if (replace_tabs) { chars = " "; indentation /= replace_tabs; // QPlainTextEdit::keyPressEvent(e); } if (line.endsWith(":")) { qDebug() << line.endsWith(":"); if (replace_tabs) { indentation += 1; } QPlainTextEdit::keyPressEvent(e); this->insertPlainText(chars.repeated(indentation)); } else { QPlainTextEdit::keyPressEvent(e); this->insertPlainText(chars.repeated(indentation)); } } else { QPlainTextEdit::keyPressEvent(e); } }
and the header file:
#define PLAINTEXTEDIT_H #include <QPlainTextEdit> class PlainTextEdit : public QPlainTextEdit { public: PlainTextEdit(QWidget *parent = nullptr); QFont *font; void move_cursor_back(); int replace_tabs; QList<int> key_list; protected: void keyPressEvent(QKeyEvent *event) override; }; #endif // PLAINTEXTEDIT_H
-
I still have no idea how to fix it :(
-
Hi
You should try with clean default GUI project and see if still happens.
It could be inside Qt somehow.also ,what happens if u put break point in keyPressEvent
and follow program with single step pressing the delete ?update:
fast tried with your subclass and it hung the app when trying to delete spaces
so its fair to say its just some bug. -
Hi
Bug was that there was an uninitialized variable in for loop causing it to
skip/malfunctionin the
else if (key == 16777219 && .... if (!stripped_string.length()) { for (int i=0; i < end - start; i++) { <<<< was not set to zero this->textCursor().deletePreviousChar(); }
after setting it, it seems to work for me.
Final note: Using magic numbers for all keys even when they do they have keycodes
is a not optimal. It makes the logic much harder to read. -
Thank you, but here is another question:
Before I saw your solution, I compiled it in release mode and it worked perfectly.
Why does it work in release mode and not in debug mode? -
@Fuchsiaff because you had luck.
undefined behaviour may result in anything: correct operation, data disturbance or crashes. it's just undefined.
-
@Fuchsiaff
To clarify further from @aha_1980:i
was uninitialized. Its starting value was undefined. Specifically, it would have taken the value of whatever happened to be in memory where it was allocated. Now, between Debug & Release modes it is not uncommon for a memory location to be zero in one and something non-zero in the other (or indeed any two numbers).There is a moral here: when you see such a difference in behaviour in your code between Debug & Release, one of the first things you should be thinking about is the possibility of an uninitialized variable, an undefined function return result, etc.