Ejemplo de menús
El ejemplo de menús muestra cómo se pueden utilizar los menús en una aplicación de ventana principal.
Un widget de menú puede ser un menú desplegable en una barra de menús o un menú contextual independiente. Los menús desplegables se muestran en la barra de menús cuando el usuario hace clic en el elemento correspondiente o pulsa la tecla de acceso directo especificada. Los menús contextuales suelen invocarse mediante alguna tecla especial del teclado o haciendo clic con el botón derecho del ratón.

Un menú consiste en una lista de elementos de acción. En las aplicaciones, muchos comandos comunes pueden invocarse a través de menús, botones de la barra de herramientas y atajos de teclado. Dado que el usuario espera que los comandos se ejecuten de la misma forma, independientemente de la interfaz de usuario utilizada, resulta útil representar cada comando como una acción.
El ejemplo de Menús consiste en una única clase, MainWindow, derivada de la clase QMainWindow. Al elegir uno de los elementos de acción en nuestra aplicación, se mostrará la ruta del elemento en su widget central.
Definición de la clase MainWindow
QMainWindow proporciona una ventana principal de la aplicación, con una barra de menú, barras de herramientas, widgets de acoplamiento y una barra de estado alrededor de un gran widget central.
class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); protected: #ifndef QT_NO_CONTEXTMENU void contextMenuEvent(QContextMenuEvent *event) override; #endif // QT_NO_CONTEXTMENU
En este ejemplo, veremos cómo implementar menús desplegables así como un menú contextual. Para implementar un menú contextual personalizado debemos reimplementar la función contextMenuEvent() de QWidget para recibir los eventos de menú contextual de nuestra ventana principal.
private slots: void newFile(); void open(); void save(); void print(); void undo(); void redo(); void cut(); void copy(); void paste(); void bold(); void italic(); void leftAlign(); void rightAlign(); void justify(); void center(); void setLineSpacing(); void setParagraphSpacing(); void about(); void aboutQt();
También debemos implementar una colección de ranuras privadas para responder a la activación por parte del usuario de cualquiera de las entradas de nuestro menú. Nótese que estas ranuras se dejan fuera de esta documentación ya que son triviales, es decir, la mayoría de ellas sólo muestran la ruta de la acción en el widget central de la ventana principal.
private: void createActions(); void createMenus();
Hemos optado por simplificar el constructor implementando dos funciones privadas de conveniencia para crear las distintas acciones, para añadirlas a los menús y para insertar los menús en la barra de menús de nuestra ventana principal.
QMenu *fileMenu; QMenu *editMenu; QMenu *formatMenu; QMenu *helpMenu; QActionGroup *alignmentGroup; QAction *newAct; QAction *openAct; QAction *saveAct; QAction *printAct; QAction *exitAct; QAction *undoAct; QAction *redoAct; QAction *cutAct; QAction *copyAct; QAction *pasteAct; QAction *boldAct; QAction *italicAct; QAction *leftAlignAct; QAction *rightAlignAct; QAction *justifyAct; QAction *centerAct; QAction *setLineSpacingAct; QAction *setParagraphSpacingAct; QAction *aboutAct; QAction *aboutQtAct; QLabel *infoLabel; };
Por último, declaramos los distintos menús y acciones, así como una simple etiqueta de información en el ámbito de la aplicación.
La clase QMenu proporciona un widget de menú para su uso en barras de menú, menús contextuales y otros menús emergentes, mientras que la clase QAction proporciona una acción abstracta de interfaz de usuario que puede insertarse en widgets.
En algunas situaciones es útil agrupar acciones, por ejemplo, tenemos una acción Left Align, una acción Right Align, una acción Justify, y una acción Center, y queremos que sólo una de estas acciones esté activa en un momento dado. Una forma sencilla de conseguirlo es agrupar las acciones en un grupo de acciones utilizando la clase QActionGroup.
Implementación de la clase MainWindow
En el constructor, empezamos creando un QWidget normal y lo convertimos en el widget central de nuestra ventana principal. Observa que la ventana principal toma posesión del puntero del widget y lo borra en el momento apropiado.
MainWindow::MainWindow() { QWidget *widget = new QWidget; setCentralWidget(widget); QWidget *topFiller = new QWidget; topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); infoLabel = new QLabel(tr("<i>Choose a menu option, or right-click to " "invoke a context menu</i>")); infoLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); infoLabel->setAlignment(Qt::AlignCenter); QWidget *bottomFiller = new QWidget; bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(5, 5, 5, 5); layout->addWidget(topFiller); layout->addWidget(infoLabel); layout->addWidget(bottomFiller); widget->setLayout(layout);
A continuación, creamos la etiqueta de información, así como un relleno superior e inferior que añadimos a un diseño que instalamos en el widget central. Los objetos QMainWindow vienen con su propio diseño personalizado y establecer un diseño en una ventana principal real, o crear un diseño con una ventana principal como padre, se considera un error. Siempre debes establecer tu propio diseño en el widget central.
createActions();
createMenus();
QString message = tr("A context menu is available by right-clicking");
statusBar()->showMessage(message);
setWindowTitle(tr("Menus"));
setMinimumSize(160, 160);
resize(480, 320);
}Para crear las acciones y menús llamamos a nuestras dos funciones de conveniencia: createActions() y createMenus(). Volveremos a ellas en breve.
QMainWindowLa función statusBar() devuelve la barra de estado de la ventana principal (si la barra de estado no existe, esta función creará y devolverá una barra de estado vacía). Inicializamos la barra de estado y el título de la ventana, redimensionamos la ventana a un tamaño apropiado y nos aseguramos de que la ventana principal no pueda ser redimensionada a un tamaño menor que el dado.
Ahora, echemos un vistazo más de cerca a la función de conveniencia createActions() que crea las diversas acciones:
void MainWindow::createActions() { newAct = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::DocumentNew), tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); connect(newAct, &QAction::triggered, this, &MainWindow::newFile); ...
Un objeto QAction puede contener un icono, un texto, un acceso directo, un consejo de estado, un texto "¿Qué es esto?" y un tooltip. La mayoría de estos elementos se pueden definir en el constructor, pero también se pueden definir de forma independiente utilizando las funciones de conveniencia proporcionadas.
En la función createActions(), primero creamos una acción newAct, pasando el texto y un icono utilizando una de las constantes de icono del tema. Hacemos de Ctrl+N su acceso directo utilizando la función QAction::setShortcut(), y establecemos su información de estado utilizando la función QAction::setStatusTip() (la información de estado se muestra en todas las barras de estado proporcionadas por el widget padre de nivel superior de la acción). También conectamos su señal triggered() a la ranura newFile().
El resto de las acciones se crean de forma similar. Para más detalles, consulte el código fuente.
alignmentGroup = new QActionGroup(this); alignmentGroup->addAction(leftAlignAct); alignmentGroup->addAction(rightAlignAct); alignmentGroup->addAction(justifyAct); alignmentGroup->addAction(centerAct); leftAlignAct->setChecked(true); }
Una vez que hemos creado las acciones Left Align, Right Align, Justify, y una Center, también podemos crear el grupo de acciones anteriormente mencionado.
Cada acción se añade al grupo utilizando la función addAction() de QActionGroup. Nótese que una acción también puede añadirse a un grupo creándolo con el grupo como padre. Dado que un grupo de acciones es exclusivo por defecto, sólo se comprueba una de las acciones del grupo en cada momento (esto puede modificarse mediante la función QActionGroup::setExclusive()).
Una vez creadas todas las acciones, utilizamos la función createMenus() para añadir las acciones a los menús e insertar los menús en la barra de menús:
void MainWindow::createMenus() { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(newAct); fileMenu->addAction(openAct); fileMenu->addAction(saveAct); fileMenu->addAction(printAct); fileMenu->addSeparator(); fileMenu->addAction(exitAct); editMenu = menuBar()->addMenu(tr("&Edit")); editMenu->addAction(undoAct); editMenu->addAction(redoAct); editMenu->addSeparator(); editMenu->addAction(cutAct); editMenu->addAction(copyAct); editMenu->addAction(pasteAct); editMenu->addSeparator(); helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(aboutAct); helpMenu->addAction(aboutQtAct);
QMenuBarLa función addMenu() de QMenu añade un nuevo con el título dado a la barra de menús (tenga en cuenta que la barra de menús se apropia del menú). Utilizamos la función addAction() de QWidget para añadir cada acción al menú correspondiente.
Alternativamente, la clase QMenu proporciona varias funciones de conveniencia addAction() que crean y añaden nuevas acciones a partir de textos y/o iconos dados. También puede proporcionar un miembro que se conectará automáticamente a la señal triggered() de la nueva acción, y un acceso directo representado por una instancia QKeySequence.
La función QMenu::addSeparator() crea y devuelve una nueva acción separadora, es decir, una acción para la que QAction::isSeparator() devuelve verdadero, y añade la nueva acción a la lista de acciones del menú.
formatMenu = editMenu->addMenu(tr("&Format")); formatMenu->addAction(boldAct); formatMenu->addAction(italicAct); formatMenu->addSeparator()->setText(tr("Alignment")); formatMenu->addAction(leftAlignAct); formatMenu->addAction(rightAlignAct); formatMenu->addAction(justifyAct); formatMenu->addAction(centerAct); formatMenu->addSeparator(); formatMenu->addAction(setLineSpacingAct); formatMenu->addAction(setParagraphSpacingAct); }
Observe el menú Format. En primer lugar, se añade como submenú al menú Edit mediante la función addMenu() de QMenu. En segundo lugar, eche un vistazo a las acciones de alineación: En la función createActions() añadimos las acciones leftAlignAct, rightAlignAct, justifyAct y centerAct a un grupo de acciones. Sin embargo, debemos añadir cada acción al menú por separado mientras el grupo de acciones hace su magia entre bastidores.
#ifndef QT_NO_CONTEXTMENU void MainWindow::contextMenuEvent(QContextMenuEvent *event) { QMenu menu(this); menu.addAction(cutAct); menu.addAction(copyAct); menu.addAction(pasteAct); menu.exec(event->globalPos()); } #endif // QT_NO_CONTEXTMENU
Para proporcionar un menú contextual personalizado, debemos reimplementar la función contextMenuEvent() de QWidget para recibir los eventos del menú contextual del widget (ten en cuenta que la implementación por defecto simplemente ignora estos eventos).
Cada vez que recibimos un evento de este tipo, creamos un menú que contiene las acciones Cut, Copy y Paste. Los menús contextuales pueden ejecutarse de forma asíncrona utilizando la función popup() o de forma síncrona utilizando la función exec(). En este ejemplo, hemos elegido mostrar el menú utilizando la función exec(). Pasando la posición del evento como argumento nos aseguramos de que el menú contextual aparece en la posición esperada.
© 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.