Para crear una lista desplegable en Qt Quick, usaremos el componente ComboBox. Cuando ejecutes esta aplicación, verás un ComboBox que despliega la lista de elementos. Al seleccionar un elemento, se mostrará en la parte superior del ComboBox, y se imprimirá en la consola el elemento seleccionado.
import QtQuick
import QtQuick.Controls
ApplicationWindow {
visible: true
width: 400
height: 200
title: "Lista Desplegable"
ComboBox {
id: comboBox
width: parent.width - 20
model: ListModel {
ListElement { text: "Elemento 1" }
ListElement { text: "Elemento 2" }
ListElement { text: "Elemento 3" }
}
onCurrentIndexChanged: {
var selectedText = model.get(currentIndex).text;
console.log("Seleccionaste: " + selectedText);
}
}
}

En este ejemplo, hemos utilizado un ComboBox que muestra una lista de elementos desplegables. Los elementos se definen en un modelo, y cuando seleccionas un elemento en el ComboBox, se ejecuta la función onCurrentIndexChanged, que imprime el elemento seleccionado en la consola.
Un ejemplo más elaborado: Crear, copiar los códigos y ejecutar el proyecto que contiene los 3 archivos siguientes: myObject.h, main.cpp y Main.qml:
myObject.h
// MyObject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QObject>
#include <QQmlContext>
#include <QtQml>
class MyObject : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(int new_generateNumber MEMBER my_generateNumber NOTIFY generateNumber_slot);
public:
explicit MyObject(QObject *parent = nullptr);
Q_INVOKABLE void generateNumber(int min, int max);
Q_INVOKABLE int getX();
public slots:
void generateNumber_slot();
signals:
void generateNumber_signal(int);
private:
int my_generateNumber = 0;
};
#endif // MYOBJECT_H
Aquí está una descripción de las principales líneas del código anterior:
- Inclusión de cabeceras: El código incluye varias cabeceras de Qt, como
QObject,QQmlContext,QtQml, que son necesarias para trabajar con Qt Quick y para la creación de objetos QML. - Declaración de la clase
MyObject: La clase creadaMyObjectse deriva deQObject, lo que la hace una clase que puede ser utilizada en el sistema de objetos de Qt. Además, se marca con la macroQ_OBJECT, que es necesaria para habilitar la funcionalidad de señales y ranuras de Qt. - Uso de la macro
QML_ELEMENT: Esta macro se usa para registrar la clase como un elemento QML, lo que permite su uso en archivos QML. - Declaración de una propiedad QML: Se declara una propiedad llamada
new_generateNumberque se conecta al miembromy_generateNumber. Esto permitirá a los objetos QML acceder y modificar el valor demy_generateNumbera través de esta propiedad. - Métodos Q_INVOKABLE: Se declaran dos métodos marcados como
Q_INVOKABLE. Estos métodos pueden ser llamados desde el código QML.generateNumbertoma dos parámetros (min y max) ygetXno toma ningún parámetro.generateNumber_slotes un método público que se puede invocar desde fuera de la clase. - Signals y slots: Se declara una señal llamada
generateNumber_signalque emite un entero como argumento. También hay un slot llamadogenerateNumber_slot. Las señales y los slots se utilizan para la comunicación entre objetos en Qt.
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDebug>
#include <QRandomGenerator>
#include "MyObject.h"
// Funciones para manejar las señales
MyObject::MyObject(QObject *parent)
: QObject(parent)
{
QObject::connect(this, &MyObject::generateNumber_signal, this, &MyObject::generateNumber_slot);
}
void MyObject::generateNumber_slot(){
my_generateNumber++;
qInfo() << "Dentro de slot:" << my_generateNumber;
}
int MyObject::getX()
{
return 10;
}
QStringList getList()
{
QStringList dataList = {
"Item A",
"Item B",
"Item C",
"Item D"
};
return dataList;
}
void MyObject::generateNumber(int min, int max)
{
const int num_aleatorio = QRandomGenerator::global()->bounded(min,max);
qDebug() << "Called the c++ signal with num_aleatorio" << num_aleatorio;
emit generateNumber_signal(num_aleatorio);
}
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/MiProyectoQtQuick_1/Main.qml"_qs);
engine.load(url);
if (engine.rootObjects().isEmpty())
return -1;
engine.rootContext()->setContextProperty("comboModel2", getList() );
return app.exec();
}
Este código anterior es la implementación principal de la aplicación en C++ que utiliza Qt y Qt Quick para crear una interfaz de usuario y conectarla con la clase MyObject que hemos definido previamente:
- Incluye las cabeceras necesarias, como
QGuiApplication,QQmlApplicationEngine,QQmlContext,QDebug,QRandomGeneratory el archivo de cabecera"MyObject.h", que contiene la definición de la claseMyObject. - En la función
main, se crea una instancia deQGuiApplicationpara manejar la aplicación y una instancia deQQmlApplicationEnginepara cargar y ejecutar la interfaz de usuario QML. - Se carga el archivo QML principal (
Main.qml) desde un recurso Qt utilizando la URLqrc:/MiProyectoQtQuick_1/Main.qml. - Si la carga del motor de aplicaciones QML tiene éxito, se establece el contexto de la raíz del motor para exponer un modelo de datos (
comboModel2) al QML. En este caso, el modelo de datos es una lista de cadenas obtenidas de la funcióngetList(). - Se ejecuta la aplicación llamando a
app.exec(), lo que inicia el bucle principal de la aplicación y muestra la ventana de la interfaz de usuario. - En el código de la clase
MyObject, se definen las funciones que se conectan a señales y se pueden llamar desde QML. La funcióngenerateNumber_slotse conecta a la señalgenerateNumber_signal, y cuando se emite esta señal, incrementa el valor demy_generateNumbery muestra un mensaje de registro con el nuevo valor. La funcióngetXsimplemente devuelve el valor 10. - La función
generateNumbergenera un número aleatorio entre los valoresminymax, emite la señalgenerateNumber_signalcon ese número y muestra un mensaje de registro con el número aleatorio generado.
Main.qml
import QtQuick 2.3
import QtQuick.Controls 2.2
import QtQuick.Layouts
import QtQuick.Controls.Material
import MiProyectoQtQuick_1
ApplicationWindow {
id: window1
visible: true
width: 640
height: 480
title: qsTr("App: " + windowTitle)
property string windowTitle: "Hola Mundo"
property int randNum:0
MyObject {
id: myObject
onGenerateNumber_signal: (num) => {
randNum = num
}
}
ComboBox {
id: comboBox1
x: 258
y: 50
model: comboModel
onActivated: {
console.log("ComboBox activated:" + comboBox1.currentIndex)
}
}
ComboBox {
id: comboBox2
currentIndex: 0
model: comboModel2
x: 258
y: 120
}
ListModel {
id: comboModel
ListElement { text: "Item 1" }
ListElement { text: "Item 2" }
ListElement { text: "Item 3" }
}
Button {
id: button1
x: 258
y: 200
text: qsTr("Remove Item de ComboBox1")
onClicked: comboModel.remove(comboBox1.currentIndex)
}
Button {
id: button2
x: 258
y: 250
text: qsTr("Add Item al ComboBox1")
onClicked: comboModel.insert(0, { text: "Nuevo Item" })
}
Button {
id: button3
x: 258
y: 300
text: qsTr("Add Item desde Función C++")
onClicked: {
onClicked: comboModel.insert(0, { text: myObject.getX().toString() })
console.log(" X=" + myObject.getX())
}
}
Button {
id: button4
x: 258
y: 350
text: qsTr("Add Item desde Signal C++")
onClicked: {
myObject.generateNumber(1, 5)
onClicked: comboModel.insert(0, { text: randNum.toString() })
}
}
Button {
id: button5
x: 258
y: 400
text: qsTr("Add Item desde Slot C++")
onClicked: {
myObject.new_generateNumber++
onClicked: comboModel.insert(0, { text: myObject.new_generateNumber.toString() })
}
}
}
El código anterior es una interfaz de usuario en QML que utiliza el objeto MyObject que hemos definido previamente en C++.
- Importaciones: Se importan varios módulos de Qt Quick y Qt Quick Controls que se utilizarán en la interfaz de usuario. Además, se importa un módulo llamado
MiProyectoQtQuick_1, que contiene la definición de la claseMyObjectque creamos. ApplicationWindow: Se crea una ventana de la aplicación (ApplicationWindow) con propiedades comowidth,height,title, etc. Se define una propiedadwindowTitleque se utiliza como título de la ventana y una propiedadrandNumque se utiliza para almacenar un número generado desde el objetoMyObject.MyObject: Se crea una instancia de la claseMyObjectcon el idmyObject. Cuando la señalgenerateNumber_signaldemyObjectse emite, se actualiza la propiedadrandNumcon el valor emitido.ComboBox: Se crean dos listas despegables (ComboBox) concomboBox1ycomboBox2.comboBox1utiliza un modelo llamadocomboModelque contiene elementos de lista.comboBox2utiliza un modelo llamadocomboModel2.ListModel: Se define un modelo llamadocomboModelque contiene elementos de lista (ListElement) con texto, que se utilizarán encomboBox1. Este modelo se inicializa con tres elementos.- Botones: Se crean cinco botones con etiquetas y funciones asociadas:
button1: Elimina el elemento seleccionado encomboBox1.button2: Inserta un nuevo elemento al principio decomboBox1.button3: Llama a la funcióngetXdemyObjectpara obtener un valor desde C++ y lo inserta al principio decomboBox1.button4: Llama al métodogenerateNumberdemyObjectpara generar un número y lo inserta al principio decomboBox1.button5: Incrementa la propiedadnew_generateNumberdemyObjecty lo inserta al principio decomboBox1.


Thank you for your sharing. I am worried that I lack creative ideas. It is your article that makes me full of hope. Thank you. But, I have a question, can you help me?