Text Editing Components in Qt Framework

Overview of Qt Text Editing Widgets

Qt provides three primary text editing components, each designed for specific use cases:

  • QLineEdit – A single-line text input widget suitable for forms, search boxes, and simple data entry.
  • QTextEdit – A multi-line rich text editor supporting formatted text, images, tables, and other embedded content.
  • QPlainTextEdit – A multi-line plain text editor optimized for handling large amounts of unformatted text.

Inheritance Hierarchy

All three components inherit from QWidget. Both QTextEdit and QPlainTextEdit derive from QAbstractScrollArea, providing built-in scrolling capabilities.

Feature Comparison

ComponentLine SupportContent TypeRich TextPerformance
QLineEditSingle linePlain textNoHigh
QTextEditMulti-lineRich textYesMedium
QPlainTextEditMulti-linePlain textNoHigh

Practical Demonstration

The following example illustrates how each component handles text and embedded content differently:

#include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent) 
    : QMainWindow(parent)
    , m_singleLineEditor(this)
    , m_plainTextEditor(this)
    , m_richTextEditor(this)
{
    setupUi();
}

void MainWindow::setupUi()
{
    setWindowSize(600, 420);
    configureSingleLineEdit();
    configurePlainTextEdit();
    configureRichTextEdit();
}

void MainWindow::setWindowSize(int width, int height)
{
    resize(width, height);
}

void MainWindow::configureSingleLineEdit()
{
    m_singleLineEditor.setGeometry(20, 20, 560, 100);
    m_singleLineEditor.setText("QLineEdit Demo");
}

void MainWindow::configurePlainTextEdit()
{
    m_plainTextEditor.setGeometry(20, 130, 560, 130);
    m_plainTextEditor.appendPlainText("QPlainTextEdit Example");
    m_plainTextEditor.appendPlainText("<img src=\"image.png\" />");
}

void MainWindow::configureRichTextEdit()
{
    m_richTextEditor.setGeometry(20, 270, 560, 130);
    m_richTextEditor.appendPlainText("QTextEdit Example");
    m_richTextEditor.appendHtml("<img src=\"image.png\" />");
}

The key difference is that QTextEdit renders HTML content as actual images, while QPlainTextEdit displays the HTML markup as literal text.

Building a Simple Notepad Application

A practical text editor requires menu bars, toolbars, and status bars. Below is a complete implementation:

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPlainTextEdit>
#include <QLabel>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QToolBar>
#include <QStatusBar>

class NotepadWindow : public QMainWindow
{
    Q_OBJECT

public:
    static NotepadWindow* create();
    ~NotepadWindow();

private:
    NotepadWindow(QWidget *parent = nullptr);
    
    bool initializeComponents();
    bool setupMenuBar();
    bool setupToolBar();
    bool setupStatusBar();
    bool setupEditorArea();
    
    bool createFileMenu(QMenuBar* menuBar);
    bool createEditMenu(QMenuBar* menuBar);
    bool createFormatMenu(QMenuBar* menuBar);
    bool createViewMenu(QMenuBar* menuBar);
    bool createHelpMenu(QMenuBar* menuBar);
    bool createToolBarActions(QToolBar* toolBar);
    
    bool createAction(QAction*& action, const QString& label, int shortcutKey);
    bool createAction(QAction*& action, const QString& tooltip, const QString& iconPath);

    QPlainTextEdit* m_editor;
    QLabel* m_cursorPositionLabel;
};

#endif

MainWindow.cpp

#include "MainWindow.h"

NotepadWindow::NotepadWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_editor(new QPlainTextEdit(this))
    , m_cursorPositionLabel(new QLabel(this))
{
}

NotepadWindow* NotepadWindow::create()
{
    NotepadWindow* window = new NotepadWindow();
    
    if (!window || !window->initializeComponents()) {
        delete window;
        return nullptr;
    }
    
    return window;
}

bool NotepadWindow::initializeComponents()
{
    return setupMenuBar() && 
           setupToolBar() && 
           setupStatusBar() && 
           setupEditorArea();
}

bool NotepadWindow::setupMenuBar()
{
    QMenuBar* menuBar = this->menuBar();
    
    return createFileMenu(menuBar) &&
           createEditMenu(menuBar) &&
           createFormatMenu(menuBar) &&
           createViewMenu(menuBar) &&
           createHelpMenu(menuBar);
}

bool NotepadWindow::setupToolBar()
{
    QToolBar* toolBar = addToolBar("MainToolbar");
    toolBar->setMovable(false);
    toolBar->setFloatable(false);
    toolBar->setIconSize(QSize(16, 16));
    
    return createToolBarActions(toolBar);
}

bool NotepadWindow::setupStatusBar()
{
    QStatusBar* status = statusBar();
    
    m_cursorPositionLabel->setMinimumWidth(200);
    m_cursorPositionLabel->setAlignment(Qt::AlignHCenter);
    m_cursorPositionLabel->setText("Ln: 1    Col: 1");
    
    QLabel* authorLabel = new QLabel("Notepad Demo", this);
    authorLabel->setMinimumWidth(200);
    authorLabel->setAlignment(Qt::AlignHCenter);
    
    status->addPermanentWidget(new QLabel());
    status->addPermanentWidget(m_cursorPositionLabel);
    status->addPermanentWidget(authorLabel);
    
    return true;
}

bool NotepadWindow::setupEditorArea()
{
    setCentralWidget(m_editor);
    return true;
}

bool NotepadWindow::createFileMenu(QMenuBar* menuBar)
{
    QMenu* fileMenu = new QMenu("File(&F)");
    QAction* act = nullptr;
    
    if (!createAction(act, "New(&N)", Qt::CTRL + Qt::Key_N)) return false;
    fileMenu->addAction(act);
    fileMenu->addSeparator();
    
    if (!createAction(act, "Open(&O)...", Qt::CTRL + Qt::Key_O)) return false;
    fileMenu->addAction(act);
    fileMenu->addSeparator();
    
    if (!createAction(act, "Save(&S)", Qt::CTRL + Qt::Key_S)) return false;
    fileMenu->addAction(act);
    fileMenu->addSeparator();
    
    if (!createAction(act, "Save As(&A)...", 0)) return false;
    fileMenu->addAction(act);
    fileMenu->addSeparator();
    
    if (!createAction(act, "Print(&P)...", Qt::CTRL + Qt::Key_P)) return false;
    fileMenu->addAction(act);
    fileMenu->addSeparator();
    
    if (!createAction(act, "Exit(&X)", 0)) return false;
    fileMenu->addAction(act);
    
    menuBar->addMenu(fileMenu);
    return true;
}

bool NotepadWindow::createEditMenu(QMenuBar* menuBar)
{
    QMenu* editMenu = new QMenu("Edit(&E)");
    QAction* act = nullptr;
    
    if (!createAction(act, "Undo(&U)", Qt::CTRL + Qt::Key_Z)) return false;
    editMenu->addAction(act);
    editMenu->addSeparator();
    
    if (!createAction(act, "Redo(&R)", Qt::CTRL + Qt::Key_Y)) return false;
    editMenu->addAction(act);
    editMenu->addSeparator();
    
    if (!createAction(act, "Cut(&T)", Qt::CTRL + Qt::Key_X)) return false;
    editMenu->addAction(act);
    editMenu->addSeparator();
    
    if (!createAction(act, "Copy(&C)", Qt::CTRL + Qt::Key_C)) return false;
    editMenu->addAction(act);
    editMenu->addSeparator();
    
    if (!createAction(act, "Paste(&P)", Qt::CTRL + Qt::Key_V)) return false;
    editMenu->addAction(act);
    editMenu->addSeparator();
    
    if (!createAction(act, "Delete(&L)", Qt::Key_Delete)) return false;
    editMenu->addAction(act);
    editMenu->addSeparator();
    
    if (!createAction(act, "Find(&F)...", Qt::CTRL + Qt::Key_F)) return false;
    editMenu->addAction(act);
    editMenu->addSeparator();
    
    if (!createAction(act, "Replace(&R)...", Qt::CTRL + Qt::Key_H)) return false;
    editMenu->addAction(act);
    editMenu->addSeparator();
    
    if (!createAction(act, "Go To(&G)", Qt::CTRL + Qt::Key_G)) return false;
    editMenu->addAction(act);
    editMenu->addSeparator();
    
    if (!createAction(act, "Select All(&A)", Qt::CTRL + Qt::Key_A)) return false;
    editMenu->addAction(act);
    
    menuBar->addMenu(editMenu);
    return true;
}

bool NotepadWindow::createFormatMenu(QMenuBar* menuBar)
{
    QMenu* formatMenu = new QMenu("Format(&O)");
    QAction* act = nullptr;
    
    if (!createAction(act, "Word Wrap(&W)", 0)) return false;
    formatMenu->addAction(act);
    formatMenu->addSeparator();
    
    if (!createAction(act, "Font(&F)...", 0)) return false;
    formatMenu->addAction(act);
    
    menuBar->addMenu(formatMenu);
    return true;
}

bool NotepadWindow::createViewMenu(QMenuBar* menuBar)
{
    QMenu* viewMenu = new QMenu("View(&V)");
    QAction* act = nullptr;
    
    if (!createAction(act, "Toolbar(&T)", 0)) return false;
    viewMenu->addAction(act);
    viewMenu->addSeparator();
    
    if (!createAction(act, "Status Bar(&S)", 0)) return false;
    viewMenu->addAction(act);
    
    menuBar->addMenu(viewMenu);
    return true;
}

bool NotepadWindow::createHelpMenu(QMenuBar* menuBar)
{
    QMenu* helpMenu = new QMenu("Help(&H)");
    QAction* act = nullptr;
    
    if (!createAction(act, "User Guide", 0)) return false;
    helpMenu->addAction(act);
    helpMenu->addSeparator();
    
    if (!createAction(act, "About Notepad...", 0)) return false;
    helpMenu->addAction(act);
    
    menuBar->addMenu(helpMenu);
    return true;
}

bool NotepadWindow::createToolBarActions(QToolBar* toolBar)
{
    QAction* act = nullptr;
    
    if (!createAction(act, "New", ":/icons/new.png")) return false;
    toolBar->addAction(act);
    
    if (!createAction(act, "Open", ":/icons/open.png")) return false;
    toolBar->addAction(act);
    
    if (!createAction(act, "Save", ":/icons/save.png")) return false;
    toolBar->addAction(act);
    
    if (!createAction(act, "Save As", ":/icons/saveas.png")) return false;
    toolBar->addAction(act);
    
    if (!createAction(act, "Print", ":/icons/print.png")) return false;
    toolBar->addAction(act);
    
    if (!createAction(act, "Undo", ":/icons/undo.png")) return false;
    toolBar->addAction(act);
    
    if (!createAction(act, "Redo", ":/icons/redo.png")) return false;
    toolBar->addAction(act);
    
    return true;
}

bool NotepadWindow::createAction(QAction*& action, const QString& label, int shortcutKey)
{
    action = new QAction(label, this);
    if (!action) return false;
    
    if (shortcutKey != 0) {
        action->setShortcut(QKeySequence(shortcutKey));
    }
    
    return true;
}

bool NotepadWindow::createAction(QAction*& action, const QString& tooltip, const QString& iconPath)
{
    action = new QAction(this);
    if (!action) return false;
    
    action->setToolTip(tooltip);
    action->setIcon(QIcon(iconPath));
    
    return true;
}

NotepadWindow::~NotepadWindow()
{
}

main.cpp

#include <QApplication>
#include "MainWindow.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    
    NotepadWindow* window = NotepadWindow::create();
    if (!window) {
        return -1;
    }
    
    window->show();
    return app.exec();
}

Key Characteristics of Qt Text Widgets

  • QLineEdit is ideal for simple input fields such as usernames, passwords, and search queries.
  • QTextEdit supports rich text formatting including HTML tags, making it suitable for document editors and chat applications.
  • QPlainTextEdit offers superior performance for large plain text files, making it the preferred choice for code editors and log viewers.

All three widgets provide built-in support for standard editing operations including cut, copy, paste, undo, redo, and drag-and-drop functionality.

Tags: Qt QLineEdit QTextEdit QPlainTextEdit GUI Development

Posted on Sat, 06 Jun 2026 17:45:44 +0000 by fourlincoln10