7. Text Widgets

While Qt buttons and the numeric widgets let the user enter binary and numerical data, text widgets support plain text and rich text input. Qt offers three text widgets:

  • QLineEdit - single-line plain-text editing,
  • QTextEdit - provides multi-line richtext with Markdown and HTML1 support,
  • QPlainTextEdit - multi-line plain-text with optional support for syntax coloring.

7.1 QLineEdit

QLineEdit provides a single-line plain-text editor. It supports the usual edit operations (copy, cut, paste, undo, redo) via standard keyboard shortcuts and a built-in context menu. You can restrict input length with setMaxLength(), validate input using a QValidator or input mask, and turn the widget into a password field by setting echoMode to EchoMode.Password.

Here are the QLineEdit signals you are likely to use:

Signal When Emitted
textChanged(text) Any change to the text (user or programmatic)
textEdited(text) Only when the user types, pastes, or deletes
returnPressed() Enter/Return key is pressed
editingFinished() Enter pressed or the line edit loses focus
selectionChanged() Selected text changes
inputRejected() A validator rejects the input
An icon of a clipboard-list1

Suppose you need a text field that accepts only letters and warns the user about invalid input.

Here’s how to do it:

  1. Create a QLineEdit object, attach a regular expression validator that allows only letters, and add a Qlabel to display feedback.

  2. Implement two slots: one to show the final text when editing finishes, and another to warn the user when an invalid character is rejected.

  3. Connect the editingFinished() and inputRejected() signal to the corresponding slots.

7.2 QTextEdit

QTextEdit is a widget for displaying and editing both plain text and rich text. It can handle large documents efficiently and can be used as an advanced WYSIWYG editor that support rich text formatting via HTML or Markdown. Internally, QtextEdit uses a QTextDocument object, which organizes content in a hierarchy of frames, blocks and fragments.

Commonly used QTextEdit signals:

Signal Description
textChanged() Emitted when document’s content changes
cursorPositionChanged() Emitted when cursor position changes
copyAvailable(yes) Emitted when the availability of copy changes
redoAvailable(available) Emitted when redo becomes available/unavailable
undoAvailable(available) Emitted when undo becomes available/unavailable
selectionChanged() Emitted when current selection changes

Note: textChanged() is emitted for both user edits and programmatic changes (e.g., calling setPlainText(), setHtml(), or setMarkdown()).

An icon of a clipboard-list1

Let’s say you need to create a basic Markdown editor with side-by-side live preview.

To do it:

  1. Create the source editor. Instantiate QTextEdit for editing. Use monospace font for better allignment.

  2. Create the preview widget. Instantiate a second QTextEdit that will display the rendered Markdown. Make it read-only and give it a distinct appearance.

  3. Implement the preview slot to and connect the signal. Get the source textedit contents as plain text and use setMarkdown() to render it as Markdown in the preview textedit. By default, setMarkdown() uses the GitHub-flavored Markdown dialect.

Note that we perform the initial setPlainText() only after connecting the textChanged() signal. This ensures the slot runs immediately and the preview is rendered with the initial text.

7.3 QPlainTextEdit

QPlainTextEdit provides a widget optimized for editing and displaying plain text. Unlike QTextEdit, it does not support HTML or Markdown.

A QPlainTextEdit document is composed of characters and blocks (paragraphs) separated by newline characters. Each block contains a sequence of characters with optional formatting.

An icon of a clipboard-list1

You are tasked with creating a basic plain-text editor that uses a monospace font and shows the current cursor line and column, as well as the total text length. To do this:

  1. Create a QPlainTextEdit object, use QFontDatabase to set its font to a generic monospace font, and disable line wrapping. Also add two labels to the window: one for showing character count, and the other for showing cursor position.

  2. Implement the slots to display text stats. In update_char_count(), retrieve the character count directly from the editor’s underlying QTextDocument and display it in the label. In update_position(), use the editor’s QTextCursor to get the current block number and the current cursor position within the block, then use these to calculate the cursor’s current line (block number + 1) and column (position within the block + 1).

  3. Connect the signals to the slots. Update the character count when textChanged() emits, update cursor position when cursorPositionChanged() emits.


  1. If you don’t implement __init__() in your class at all, the parent class gets initalized automatically.↩︎

  2. https://doc.qt.io/qtforpython-6/↩︎