martes, 20 de mayo de 2014

Como colocar Widgets dentro de un QHeaderView usando el framework Qt.

clip_image002

Hace poco tuve la necesidad de lograr colocar QComboBoxes en las secciones dentro de un QHeaderView, en un inicio pensé que esto sería bastante sencillo, ya que podría utilizar el método setViewportMargins () y poner los widgets en la parte superior. Pero por desgracia esto no es posible hacerlo porque los itemviews establecen los márgenes de ventana gráfica y si se establece fuera de este puede causar problemas por lo que no se recomienda este enfoque.

Por lo tanto, la manera de conseguir que funcione es crear los widgets y colocarlos en el QHeaderView directamente, esto significa que tenemos que ajustar de forma manual cuando se cambia el tamaño de las secciones, se mueve o cuando el propio itemview se desplaza [1]. Así que para hacer esto tenemos que empezar por hacer una clase que herede de QHeaderView. En este caso me estoy centrando exclusivamente en una cabecera horizontal, ya que esto hace que sea más sencillo centrarse en lugar de tratar de darse cuenta de las secciones de dirección se están moviendo.

MyHorizontalHeader(QWidget *parent = 0) : QHeaderView(Qt::Horizontal, parent)
{
connect(this, SIGNAL(sectionResized(int, int, int)), this,
SLOT(handleSectionResized(int)));
connect(this, SIGNAL(sectionMoved(int, int, int)), this,
SLOT(handleSectionMoved(int, int, int)));
setMovable(true);
}

Hemos añadido dos slots aquí, uno es para el manejo de una sección cuando se cambia el tamaño y otro para cuando se mueve una sección. Vamos a llegar a ello dentro de poco, pero primero vamos a cubrir la inicialización de los widgets. No podemos hacer esto en el constructor (aunque podríamos hacerlo si sabemos más sobre el itemview que estará asociado, pero para este caso yo quiero ser lo más genérico posible), ya que no sabemos cuántas secciones habrá . Así que el mejor lugar para hacer esto es el método re-implementado showEvent().

void showEvent(QShowEvent *e)
{
for (int i=0;i<count();i++) {
if (!boxes[i]) {
QComboBox *box = new QComboBox(this);
boxes[i] = box;
}
boxes[i]->setGeometry(sectionViewportPosition(i), 0,
sectionSize(i) - 5, height());
boxes[i]->show();
}
QHeaderView::showEvent(e);
}

La matriz de las cajas es sólo un QMap <int, QComboBox *> con el entero que se refiere al índice lógico de la sección de la lista desplegable que está conectada. Con el fin de conseguir la posición correcta en la ventana gráfica para la sección utilizamos sectionViewportPosition () y sectionSize () se usa para obtener el tamaño de la sección. La razón del -5 existe solamente para que yo pueda ver un poco de la parte inferior para permitir el movimiento de las secciones. Si sólo desea ver el divisor para cambiar el tamaño de las secciones puede cambiar a -2.

Lo que queda entonces es reaccionar al cambio de tamaño de las secciones y el movimiento de las secciones con los siguientes slots:

void handleSectionResized(int i)
{
for (int j=visualIndex(i);j<count();j++) {
int logical = logicalIndex(j);
boxes[logical]->setGeometry(sectionViewportPosition(logical), 0,
sectionSize(logical) - 5, height());
}
}
void handleSectionMoved(int logical, int oldVisualIndex, int newVisualIndex)
{
for (int i=qMin(oldVisualIndex, newVisualIndex);i<count();i++){
int logical = logicalIndex(i);
boxes[logical]->setGeometry(sectionViewportPosition(logical), 0,
sectionSize(logical) - 5, height());
}
}

El código es fundamentalmente el mismo en ambos slots, pero el bucle está ajustado para limitar la cantidad de widgets tiene que ser tocado, cuando una sección cambia de tamaño sólo vamos a partir del índice visual de la redimensionada y llegaremos al resto de las secciones después de esa. Cuando se mueve una sección que tenemos que ir desde el primer índice visual accionado hasta el final del headerview, como las otras secciones tendrán que ser actualizados para adaptarse.
Hasta aquí todo bien, lo único que nos queda por hacer ahora es manejar el caso en que el itemview se desplaza ya que tenemos que cambiar la posición de los widgets de nuevo. Como el QHeaderView no ha sido notificado de ninguna manera que esto ocurre ya que está en la ventana que tenemos que conectar este a partir del propio itemview cuando se produce un desplazamiento. Para hacer esto necesitamos re-implementar scrollContentsBy ():

void scrollContentsBy(int dx, int dy)
{
QTableWidget::scrollContentsBy(dx, dy);
if (dx != 0)
horizHeader->fixComboPositions();
}

Lo que no se muestra aquí es el constructor que crea una instancia de la clase MyHorizontalHeader y establece con setHorizontalHeader (). Así que cada vez que el contenido se desplaza en cualquier dirección horizontal llamamos al método fixComboPositions() que hace:

void fixComboPositions()
{
for (int i=0;i<count();i++)
boxes[i]->setGeometry(sectionViewportPosition(i), 0,
sectionSize(i) - 5, height());
}

En efecto es el mismo que hace el método showEvent (), ya que no sabemos cuánto se ha hecho visible u oculta la forma más fácil es ir sobre todos los widgets.
Y ahí lo tienen, un enfoque bastante sencillo de conseguir widgets en un QHeaderView, explicado paso a paso, por lo que debería ser fácilmente adaptable para sus propias necesidades. Es todo por hoy esperamos que esta entrada le sea de utilidad.

{ Leer Más }


martes, 6 de mayo de 2014

QtSerialPort, un módulo de la biblioteca Qt que permite la comunicación a través del puerto serie.

clip_image002

El módulo QtSerialPort es una extensión (módulo add-on) para la biblioteca QT5, proporcionando una interfaz única para el hardware y los puertos serie virtuales [1]. Proporciona las funcionalidades básicas, que incluye la configuración, operaciones entrada / salida (I / O), obtener y establecer las señales de control de la interfaz RS-232.

Las interfaces seriales, debido a su sencillez y fiabilidad, siguen siendo populares en algunos sectores como el desarrollo de sistemas embebidos, robótica, etc.

Con el módulo QtSerialPort, los desarrolladores pueden reducir significativamente el tiempo necesario para implementar aplicaciones Qt que requieren acceso a una interfaz serial.

Historia
QtSerialPort se originó a partir de la biblioteca de terceros QSerialDevice [gitorious.org] (rama 2.0), que se mudó recientemente a un repositorio en https://codereview.qt-project.org/. Esto se hizo para permitir un desarrollo más abierto, y para reunir y coordinar a una comunidad que está interesada en el desarrollo de este módulo.

Funcionalidad
Actualmente, la API de módulo contiene dos clases: QSerialPort y QSerialPortInfo:

QSerialPort es la clase base del módulo y proporciona un conjunto de métodos y propiedades básicas para acceder a los recursos de los puertos serie.
Soporta los siguientes sistemas operativos:

Sistema Operativo

Estado de Sorporte

Nota

Windows NT/2K/XP/Vista/7

SI

Soporte completo

Windows CE

SI

Probado solo en emuladores de las plataformas 5 y 6

Gnu/Linux

SI

Soporte completo

MacOSX

SI

Soporte completo

Otros Unix

SI

Todos los compatibles con POSIX

Symbian1

SI

Parcialmente, probado solo en el emulador

QSerialPortInfo es una clase de ayuda. Proporciona información sobre los puertos serie disponibles en el sistema.

Soporta los siguientes sistemas operativos:

Sistema operativo

Estado de soporte

Nota

Windows NT/2K/XP/Vista/7

SI

Soporte completo (using SetupAPI)

Windows CE

SI

Probado solo en emuladores de las plataformas 5 y 6

Gnu/Linux

SI

Soporte completo (using libudev or simple search in /dev)

MacOSX

SI

Soporte completo

Otros Unix

SI

Todos los compatibles con POSIX (only simple search in /dev)

Symbian2

SI

Parcialmente, probado solo en el emulador

Ver el código fuente

Puesto en marcha recientemente un espejo público del proyecto de repositorio en Gitorious [qt.gitorious.org]

Ahora todo el mundo puede ver libremente y rápidamente los últimos cambios a través de un navegador web.

Obtener el código fuente

Para obtener la instantánea actual del código fuente como un archivo, haga clic en este enlace [qt.gitorious.org].

Para aquellos que quieren usar Git puede ejecutar el siguiente comando:

  1. git clone git://gitorious.org/qt/qtserialport.git

Construcción e Instalación

Construir e instalar desde la línea de comandos

Antes de la construcción usted necesita:

· Instalar Perl 3

· Asegurarse de que las variables de entorno están establecidas correctamente:

- Correctamente especificado la ruta de acceso al Qt4/Qt5 instalado

- Correctamente especificado la ruta para usar el compilador

- Correctamente especificado la ruta de acceso al Perl 3

· Crear un directorio de construcción que esté en el mismo nivel que el directorio con el código fuente

- /

- / SerialPort-src

- / SerialPort-build

Los siguientes son los procedimientos recomendados para la construcción de la biblioteca QtSerialPort en Qt4/Qt5 desde la línea de comandos.

  • cd serialport-build
  • qmake .. / serialport-src/qtserialport.pro
  • make [o 'nmake' para el compilador MSVC o '-make mingw32' para el compilador MinGW]
  • make install [o 'nmake install' para el compilador MSVC o 'mingw32-make install' para el compilador MinGW]

Nota: en los sistemas * nix es posible que se requieran privilegios de superusuario:

sudo make install

Construir e instalar desde la QtCreator

Antes de la construcción de lo que necesita:

  • Instalar el Perl 3 y estar convencido de que ha especificado correctamente la ruta al Perl en un ambiente global.
  • Estar convencido de que las cadenas de herramientas que desee ( kits) del QtCreator se ha configurado correctamente

Los procedimientos recomendados para la construcción de la biblioteca QtSerialPort para Qt4/Qt5 del QtCreator:

  • Descargar y desempaquetar el código fuente de QtSerialPort
  • Ejecutar QtCreator y abra el archivo de proyecto "qtserialport.pro"
  • Llegar a " Projects->(Your Kit)->Build->Build Steps "
  • Añadir un nuevo make "Build Step" y escribir en los " argumentos" (“Make arguments) el objetivo a compilar.
  • Haga clic en el menú "Rebuild Project qtserialport".

Como resultado, la biblioteca QtSerialPort será compilada e instalado automáticamente en la instancia de Qt deseada (depende del Kit seleccionado). El uso QtCreator - la manera más sencilla y rápida de instalación manual de la biblioteca.

Nota: en los sistemas *nix este método puede fallar si Qt fue instalado desde los repositorios en los directorios del sistema. Los privilegios de superusuario podrían ser necesarios para ejecutar "make install".

3 Perl sólo se requiere en el caso de QT5, consulte aquí [qt- project.org]. Al usar Qt4 omita este punto.

//**

Uso

Para utilizar la biblioteca adicione serialport al fichero *.pro de tu proyecto.

Qt4
  1. CONFIG += serialport
Qt5
  1. QT += serialport

Incluya los archivos de cabecera de QtSerialPort donde sea necesario:

  1. ...
  2. #include <QtSerialPort/QSerialPort>
  3. #include <QtSerialPort/QSerialPortInfo>
  4. ...
Ejemplo simple

Debajo se muestra un ejemplo sencillo del main.cpp:

#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
QT_USE_NAMESPACE
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// Example use QSerialPortInfo
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
qDebug() << "Name : " << info.portName();
qDebug() << "Description : " << info.description();
qDebug() << "Manufacturer: " << info.manufacturer();
// Example use QSerialPort
QSerialPort serial;
serial.setPort(info);
if (serial.open(QIODevice::ReadWrite))
serial.close();
}
return a.exec();
}

Nota: CONFIG += serial port / QT += serialport debe ser la primera o la segunda linea en tu fichero .pro.

Es todo por hoy esperamos que esta entrada le hay resultado de utilidad.

{ Leer Más }


IconIconIcon