Introducción a la programación con Qt Widgets
En este tema, enseñamos conocimientos básicos de Qt implementando una sencilla aplicación del Bloc de Notas usando C++ y el módulo Qt Widgets . La aplicación es un pequeño editor de texto que te permite crear un archivo de texto, guardarlo, imprimirlo, o reabrirlo y editarlo de nuevo. También se puede configurar el tipo de letra a utilizar.

Ejecutar el ejemplo
Para ejecutar el ejemplo desde Qt Creatorabra el modo Welcome y seleccione el ejemplo de Examples. Para más información, consulte Qt Creator: Tutorial: Construir y ejecutar.
Creación del proyecto Notepad
La creación de un nuevo proyecto en Qt Creator está asistida por un asistente que le guía paso a paso a través del proceso de creación del proyecto. El asistente le pedirá que introduzca la configuración necesaria para ese tipo concreto de proyecto y creará el proyecto por usted.
Nota: El texto de la interfaz de usuario en Qt Creator y el contenido de los archivos generados dependen de la versión de Qt Creator que utilice.

Para crear el proyecto del Bloc de notas, seleccione File > New Project > Application (Qt) > Qt Widgets Application > Choose, y siga las instrucciones del asistente. En el cuadro de diálogo Class Information, escriba Notepad como nombre de la clase y seleccione QMainWindow como clase base.

El asistente Qt Widgets Application crea un proyecto que contiene un archivo fuente principal y un conjunto de archivos que especifican una interfaz de usuario (widget del Bloc de notas):
- CMakeLists.txt - el archivo del proyecto.
- main.cpp - el archivo fuente principal de la aplicación.
- notepad.cpp - el archivo fuente de la clase notepad del widget Bloc de notas.
- notepad.h - el archivo de cabecera de la clase notepad del widget Bloc de notas.
- notepad.ui - el formulario de interfaz de usuario para el widget Bloc de notas.
Los archivos vienen con el código necesario para que puedas compilar y ejecutar el proyecto. En las siguientes secciones veremos con más detalle el contenido de los archivos.
Más información
| Acerca de | Aquí |
|---|---|
| Uso de Qt Creator | Qt Creator |
| Crear otro tipo de aplicaciones con Qt Creator | Qt Creator Tutoriales |
Fichero fuente principal
El asistente genera el siguiente código en el archivo main.cpp:
#include "notepad.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Notepad w; w.show(); return a.exec(); }
Repasaremos el código línea por línea. Las siguientes líneas incluyen los archivos de cabecera para el widget del Bloc de Notas y QApplication. Todas las clases Qt tienen un fichero de cabecera con su nombre.
#include "notepad.h" #include <QApplication>
La siguiente línea define la función main que es el punto de entrada para todas las aplicaciones basadas en C y C++:
int main(int argc, char *argv[])
La siguiente línea crea un objeto QApplication. Este objeto gestiona los recursos de toda la aplicación y es necesario para ejecutar cualquier programa Qt que utilice Qt Widgets. Construye un objeto de aplicación con argc argumentos de línea de comandos que se ejecutan en argv. (Para aplicaciones GUI que no utilizan Qt Widgets, puede utilizar QGuiApplication en su lugar).
QApplication a(argc, argv);
La siguiente línea crea el objeto Notepad. Este es el objeto para el cual el asistente creó la clase y el archivo UI. La interfaz de usuario contiene elementos visuales que en Qt se denominan widgets. Ejemplos de widgets son ediciones de texto, barras de desplazamiento, etiquetas y botones de radio. Un widget también puede ser un contenedor para otros widgets; un diálogo o una ventana principal de la aplicación, por ejemplo.
Notepad w;
La línea siguiente muestra el widget Bloc de notas en la pantalla en su propia ventana. Los widgets también pueden funcionar como contenedores. Un ejemplo de ello es QMainWindow, que a menudo contiene varios tipos de widgets. Los widgets no son visibles por defecto; la función show() hace visible el widget.
w.show();La siguiente línea hace que QApplication entre en su bucle de eventos. Cuando una aplicación Qt se está ejecutando, se generan eventos que se envían a los widgets de la aplicación. Ejemplos de eventos son las pulsaciones de ratón y de teclas.
return a.exec();
Más información
| Acerca de | Aquí |
|---|---|
| Widgets y Geometría de Ventanas | Widgets de ventana y diálogo |
| Eventos y gestión de eventos | El sistema de eventos |
Diseño de una interfaz de usuario
El asistente genera una definición de interfaz de usuario en formato XML: notepad.ui. Al abrir el archivo notepad.ui en Qt Creator, se abre automáticamente en el diseñador integrado Qt Widgets Designer.
Al compilar la aplicación, Qt Creator ejecuta Qt User Interface Compiler (uic), que lee el archivo .ui y crea el correspondiente archivo de cabecera C++, ui_notepad.h.
Uso de Qt Widgets Designer
El asistente crea una aplicación que utiliza QMainWindow. Tiene su propio diseño al que se puede añadir una barra de menú, widgets de dock, barras de herramientas y una barra de estado. El área central puede ser ocupada por cualquier tipo de widget. El asistente coloca allí el widget del Bloc de notas.
Para añadir widgets en Qt Widgets Designer:
- En el modo Qt Creator Edit , haga doble clic en el archivo notepad.ui en la vista Projects para iniciar el archivo en el Diseñador integrado Qt Widgets.
- Arrastre y suelte los widgets Text Edit (QTextEdit) al formulario.
- Pulse Ctrl+A (o Cmd+A) para seleccionar los widgets y haga clic en Lay out Vertically (o pulse Ctrl+L) para aplicar un diseño vertical (QVBoxLayout).
- Pulsa Ctrl+S (o Cmd+S) para guardar los cambios.
La interfaz de usuario tiene ahora el siguiente aspecto en Qt Widgets Designer:

Puede ver el archivo XML generado en el editor de código:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Notepad</class>
<widget class="QMainWindow" name="Notepad">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Notepad</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextEdit" name="textEdit"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
...La siguiente línea contiene la declaración XML, que especifica la versión XML y la codificación de caracteres utilizada en el documento:
<?xml version="1.0" encoding="UTF-8"?>
El resto del archivo especifica un elemento ui que define un widget del Bloc de notas:
<ui version="4.0">
El fichero UI se utiliza junto con la cabecera y el fichero fuente de la clase Bloc de Notas. Veremos el resto del archivo UI en las secciones posteriores.
Archivo de cabecera del Bloc de notas
El asistente ha generado un fichero de cabecera para la clase Bloc de Notas que contiene los #includes necesarios, un constructor, un destructor y el objeto Ui. El archivo tiene el siguiente aspecto:
#include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class Notepad; } QT_END_NAMESPACE class Notepad : public QMainWindow { Q_OBJECT public: explicit Notepad(QWidget *parent = nullptr); ~Notepad(); private: Ui::Notepad *ui; QString currentFile; };
La siguiente línea incluye QMainWindow que proporciona una ventana principal de la aplicación:
#include <QMainWindow>Las siguientes líneas declaran la clase Notepad en el espacio de nombres Ui, que es el espacio de nombres estándar para las clases UI generadas a partir de archivos .ui por la herramienta uic:
namespace Ui { class Notepad; }
La declaración de la clase contiene la macro Q_OBJECT. Debe ir en primer lugar en la definición de la clase, y declara nuestra clase como QObject. Naturalmente, también debe heredar de QObject. QObject añade varias capacidades a una clase C++ normal. En particular, el nombre de la clase y los nombres de las ranuras pueden consultarse en tiempo de ejecución. También es posible consultar los tipos de parámetros de una ranura e invocarla.
class Notepad : public QMainWindow { Q_OBJECT
Las siguientes líneas declaran un constructor que tiene un argumento por defecto llamado parent. El valor 0 indica que el widget no tiene padre (es un widget de nivel superior).
public: explicit Notepad(QWidget *parent = nullptr);
La siguiente línea declara un destructor virtual para liberar los recursos adquiridos por el objeto durante su ciclo de vida. Según la convención de nomenclatura de C++, los destructores tienen el mismo nombre que la clase a la que están asociados, precedidos de una tilde (~). En QObject, los destructores son virtuales para asegurar que los destructores de las clases derivadas son invocados correctamente cuando un objeto es borrado a través de un puntero-a-la-clase-base.
~Notepad();Las siguientes líneas declaran una variable miembro que es un puntero a la clase Notepad UI. Una variable miembro está asociada a una clase específica, y es accesible para todos sus métodos.
private: Ui::Notepad *ui; QString currentFile; };
Archivo fuente del Bloc de notas
El fichero fuente que el asistente ha generado para la clase Bloc de notas tiene el siguiente aspecto:
#include "notepad.h" #include "ui_notepad.h" Notepad::Notepad(QWidget *parent) : QMainWindow(parent), ui(new Ui::Notepad) { ui->setupUi(this); }
Las siguientes líneas incluyen el fichero de cabecera de la clase Notepad que fue generado por el asistente y el fichero de cabecera de la UI que fue generado por la herramienta uic:
#include "notepad.h" #include "ui_notepad.h"
La siguiente línea define el constructor Notepad:
Notepad::Notepad(QWidget *parent) :
La siguiente línea llama al constructor QMainWindow, que es la clase base para la clase Bloc de notas:
QMainWindow(parent),
La siguiente línea crea la instancia de la clase UI y la asigna al miembro ui:
ui(new Ui::Notepad)
La siguiente línea configura la UI:
{
ui->setupUi(this);En el destructor, borramos el ui:
Notepad::~Notepad() { delete ui; }
Archivo de proyecto
El asistente genera el siguiente fichero de proyecto, CMakeLists.txt, para nosotros:
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(notepad LANGUAGES CXX)
find_package(Qt6
REQUIRED COMPONENTS Core Gui Widgets
OPTIONAL_COMPONENTS PrintSupport
)
qt_standard_project_setup()
qt_add_executable(notepad
main.cpp
notepad.cpp notepad.h notepad.ui
)
set_target_properties(notepad PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(notepad PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
if(TARGET Qt6::PrintSupport)
target_link_libraries(notepad PRIVATE Qt6::PrintSupport)
endif()
# Resources:
set(notepad_resource_files
"images/bold.png"
"images/copy.png"
"images/create.png"
"images/cut.png"
"images/edit_redo.png"
"images/edit_undo.png"
"images/exit.png"
"images/font.png"
"images/info.png"
"images/italic.png"
"images/new.png"
"images/open.png"
"images/paste.png"
"images/pencil.png"
"images/print.png"
"images/save.png"
"images/save_as.png"
"images/underline.png"
)
qt_add_resources(notepad "notepad"
PREFIX
"/"
FILES
${notepad_resource_files}
)
install(TARGETS notepad
BUNDLE DESTINATION .
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
qt_generate_deploy_app_script(
TARGET notepad
OUTPUT_SCRIPT deploy_script
NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})El archivo de proyecto especifica los archivos fuente, de cabecera y de interfaz de usuario incluidos en el proyecto.
Más información
| Acerca de | Aquí |
|---|---|
| Uso de Qt Widgets Designer | Qt Widgets Manual del Diseñador |
| Diseños | Gestión de Layouts, Widgets y Layouts, Ejemplos de Layouts |
| Los widgets que vienen con Qt | Galería de Widgets Qt |
| Ventanas principales y clases de ventanas principales | Ventana Principal de la Aplicación, Ejemplos de Ventana Principal |
| QObjects y el modelo de Objetos Qt (Esto es esencial para entender Qt) | Modelo de Objetos |
| qmake y el sistema de construcción de Qt | Manual de qmake |
Añadiendo Interacción con el Usuario
Para añadir funcionalidad al editor, empezamos añadiendo elementos de menú y botones en una barra de herramientas.
Haga clic en "Escriba aquí", y añada las opciones Nuevo, Abrir, Guardar, Guardar como, Imprimir y Salir. Esto crea 5 líneas en el Editor de Acciones de abajo. Para conectar las acciones a las ranuras, haga clic con el botón derecho en una acción y seleccione Go to slot > triggered(), y complete el código para esa ranura determinada.
Si también queremos añadir las acciones a una barra de herramientas, podemos asignar un icono a cada QAction, y luego arrastrar el QAction a la barra de herramientas. Se asigna un icono introduciendo un nombre de icono en la propiedad Icono de la acción en cuestión. Cuando se haya arrastrado el QAction a la barra de herramientas, al hacer clic en el icono se iniciará la ranura asociada.
Complete el método newDocument():
void Notepad::newDocument() { currentFile.clear(); ui->textEdit->setText(QString()); }
La variable currentFile es una variable global que contiene el archivo que se está editando en ese momento, y clear() borra la memoria intermedia de texto. La variable currentFile está definida en la parte privada de notepad.h:
private: Ui::Notepad *ui; QString currentFile;
Abrir un archivo
En notepad.ui, haga clic con el botón derecho del ratón en actionOpen y seleccione Go to Slot.
Completa el método open().
void Notepad::open() { QString fileName = QFileDialog::getOpenFileName(this, "Open the file"); if (fileName.isEmpty()) return; QFile file(fileName); currentFile = fileName; if (!file.open(QIODevice::ReadOnly | QFile::Text)) { QMessageBox::warning(this, "Warning", "Cannot open file: " + file.errorString()); return; } setWindowTitle(fileName); QTextStream in(&file); QString text = in.readAll(); ui->textEdit->setText(text); file.close(); }
QFileDialog::getOpenFileName abre un diálogo que permite seleccionar un fichero. QFile el objeto myfile tiene como parámetro el file_name seleccionado. Almacenamos el fichero seleccionado también en la variable global currentFile para propósitos posteriores. Abrimos el fichero con file.open como fichero de texto de sólo lectura. Si no se puede abrir, se emite una advertencia y el programa se detiene.
Definimos un QTextStream instream para el parámetro myfile. El contenido del archivo myfile se copia en QString text . setText(text) llena el búfer de nuestro editor con text.
Guardar un fichero
Creamos el método para guardar un archivo de la misma manera que para Abrir un archivo, haciendo clic con el botón derecho del ratón en actionSave, y seleccionando Go to Slot.
void Notepad::save() { QString fileName; // If we don't have a filename from before, get one. if (currentFile.isEmpty()) { fileName = QFileDialog::getSaveFileName(this, "Save"); if (fileName.isEmpty()) return; currentFile = fileName; } else { fileName = currentFile; } QFile file(fileName); if (!file.open(QIODevice::WriteOnly | QFile::Text)) { QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString()); return; } setWindowTitle(fileName); QTextStream out(&file); QString text = ui->textEdit->toPlainText(); out << text; file.close(); }
QFile El objeto myfile está vinculado a la variable global current_file, la variable que contiene el fichero con el que estábamos trabajando. Si no podemos abrir myfile, se emite un mensaje de error y el método se detiene. Creamos un QTextStream outstream . El contenido de la memoria intermedia del editor se convierte en texto sin formato y, a continuación, se escribe en outstream.
Guardar un archivo con otro nombre
void Notepad::saveAs() { QString fileName = QFileDialog::getSaveFileName(this, "Save as"); if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString()); return; } currentFile = fileName; setWindowTitle(fileName); QTextStream out(&file); QString text = ui->textEdit->toPlainText(); out << text; file.close(); }
Se trata del mismo procedimiento que para Guardar un fichero, con la única diferencia de que aquí es necesario introducir un nuevo nombre para el fichero que se va a crear.
Imprimir un fichero
Si quieres utilizar las funcionalidades de impresión, necesitas añadir PrintSupport al fichero de proyecto:
find_package(Qt6
REQUIRED COMPONENTS Core Gui Widgets
OPTIONAL_COMPONENTS PrintSupport
)En notepad.cpp, declaramos un objeto QPrinter llamado printDev:
void Notepad::print() { #if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer) QPrinter printDev; #if QT_CONFIG(printdialog) QPrintDialog dialog(&printDev, this); if (dialog.exec() == QDialog::Rejected) return; #endif // QT_CONFIG(printdialog) ui->textEdit->print(&printDev); #endif // QT_CONFIG(printer) }
Lanzamos un cuadro de diálogo de impresora y almacenamos la impresora seleccionada en el objeto printDev. Si pulsamos en Cancel y no seleccionamos una impresora, el método retorna. El comando real de la impresora se da con ui->textEdit->print con nuestro objeto QPrinter como parámetro.
Seleccionar una Fuente
void Notepad::selectFont() { bool fontSelected; QFont font = QFontDialog::getFont(&fontSelected, this); if (fontSelected) ui->textEdit->setFont(font); }
Declaramos un booleano indicando si seleccionamos una fuente con QFontDialog. Si es así, establecemos la fuente con ui->textEdit->setFont(myfont).
Copiar, Cortar, Pegar, Deshacer y Rehacer
Si seleccionamos un texto y queremos copiarlo al portapapeles, llamamos al método apropiado de ui->textEdit. Lo mismo ocurre para cortar, pegar, deshacer y rehacer.
Esta tabla muestra el nombre del método a utilizar.
| Tarea | Método llamado |
|---|---|
| Copiar | ui->textEdit->copiar() |
| Cortar | ui->textEdit->cortar() |
| Pegar | ui->textEdit->pegar() |
| Deshacer | ui->textEdit->deshacer() |
| Rehacer | ui->textEdit->rehacer() |
Más información
| Acerca de | Aquí |
|---|---|
| Archivos y dispositivos de E/S | QFile, QIODevice |
| tr() e internacionalización | Qt Linguist Manual, Escribiendo el código fuente para la traducción, Internacionalización con Qt |
Construir y ejecutar desde la línea de comandos
Para compilar una aplicación de ejemplo desde la línea de comandos, cree un directorio de compilación para ella. Vaya al directorio de compilación y ejecute qt-cmake para configurar su proyecto para la compilación. Si el proyecto se configura correctamente, los archivos generados le permitirán compilar el proyecto.
md <build_directory> cd <build_directory> <qt_installation_directory>\bin\qt-cmake -GNinja <source_directory> <generator>
Los comandos crean un ejecutable en el directorio de construcción. La herramienta CMake lee el archivo del proyecto y genera instrucciones sobre cómo compilar la aplicación. A continuación, el generador utiliza las instrucciones para producir el binario ejecutable.
Por ejemplo, para compilar el ejemplo del Bloc de notas en Windows, si utiliza Ninja como generador, introduzca los siguientes comandos:
md notepad-build cd notepad-build C:\Qt\6.11.0\msvc2022_64\bin\qt-cmake -GNinja C:\Examples\notepad ninja
Si no utiliza Ninja como generador, utilice el comando CMake independiente del generador para compilar la aplicación en lugar de ninja:
cmake --build
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.