Delegates en Qt

Ejemplo de delegadosLa mayoría de las veces, con crear un modelo adecuado a nuestras clases podemos representarlas correctamente empleando las vistas existentes en Qt (p.e, listas y tablas). No obstante, hay veces que necesitamos que un campo concreto de nuestra clase se represente de una determinada forma (quizás mediante una casilla de verificación, con una barra de progreso, mediante un botón o un icono…), que además condicione la forma en la cual el usuario interactúa con ella (en el caso de una casilla de verificación, que el usuario la marque o desmarque convenientemente). ¿Cómo podemos arreglar esto? Mediante el uso de los delegados.

Para el programa Solomon, he añadido dentro de la vista principal la funcionalidad de seleccionar el tipo de ganancial con el que estamos trabajando, seleccionándolo de un combobox con dos opciones básicas: Activo y Pasivo. La forma de hacerlo es, en sí, muy sencilla, aunque pueda parecer algo intimidante al principio.

Para ello, debemos crear una nueva clase a partir de QStyledItemDelegate, y redefinir cuatro de sus métodos: paint, createEditor, setEditorData y setModelData. El primer método se encarga de dibujar nuestro delegado mientras está ‘inactivo’, es decir, mientras no se haya activado el item asociado; createEditor creará el editor necesario para modificar los datos por parte del usuario, mientas que setEditorData y setModelData se encargan de suministrar los datos necesarios al editor y al modelo, respectivamente.

Veamoslo con un ejemplo: si queremos utilizar un comboBox como delegado, deberemos crear una nueva clase, por ejemplo ComboBoxDelegate, y reescribir nuestros métodos. Para createEditor, crearíamos un comboBox, lo poblaríamos con items de selección y lo devolveríamos:

QComboBox *delegado=new QComboBox(parent);
//0==Activo, 1==Pasivo

delegado->addItem(tr("Activo"),QVariant(1));
delegado->addItem(tr("Pasivo"),QVariant(0));

return delegado;

La llamada de setEditorData pasaría al editor la información contenida en nuestra clase, en este caso un atributo con un valor 0 ó 1.

QComboBox* delegado=qobject_cast<QComboBox*>(editor);

if(index.data(Qt::EditRole).toBool())  {//true=Activo, false=Pasivo

delegado->setCurrentIndex(0);

}
else delegado->setCurrentIndex(1);

Y mediante setModelData enviaríamos la nueva información al modelo para modificar los valores de la clase.

MiModelo*modelo=qobject_cast<MiModelo*>(model);

QComboBox* comboBox=qobject_cast<QComboBox*>(editor);

modelo->setData(index,comboBox->itemData(comboBox->currentIndex()),Qt::EditRole);

El método paint es el que más problemas puede dar, ya que se encarga de dibujar en base a las opciones de estilo que estén definidas para la aplicación. O bien nos encargamos de dibujarlo todo, lo cual es un poco pesado, o bien, si estamos usando un widget relativamente ‘común’ (un comboBox, un spinBox, o un checkBox), podemos dejar que sea el propio estilo el que se encargue de dibujarlo por nosotros, mediante el método drawControl y drawComplexControl. Como ejemplo:

QStyleOptionComboBox estiloComboBox;

estiloComboBox.rect=option.rect;
estiloComboBox.state=option.state;
estiloComboBox.currentText=index.data().toString();

//Es necesario dibujar tanto el control complejo del combobox como el comboboxLabel

QApplication::style()->drawComplexControl(QStyle::CC_ComboBox,&estiloComboBox,painter);
QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel,&estiloComboBox,painter);

Podemos utilizar este truquillo para dibujar los controles más básicos dentro de nuestras vistas. Lo último que nos queda por hacer es indicarle a la vista que estamos trabajando con un delegado diferente en esa columna (o fila). ¡Y listo!

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s