martedì 30 aprile 2013

Riconoscimento impronte digitali con Thinkfinger su IBM/Lenovo T61

Prima il pacchetto ThinkFinger era disponibile come .deb ma al momento l'unica possibilita' e' di compilare il programma dai sorgenti



Si inizia quindi scaricando il sorgente della versione 0.3 dal sito di riferimento di ThinkFinger e si spacchetta

Prima di iniziare la compilazione assicurarsi di avere i seguenti pacchetti di sviluppo
apt-get install pkg-config build-essential libtool libusb-dev libpam0g-dev 

si crea la directory in cui salvare i dati

sudo mkdir /etc/pam_thinkfinger
dopo di cio' il classico

./configure --with-securedir=/lib/security --with-birdir=/etc/pam_thinkfinger
make 

e come sorpresa il pacchetto non si compila. Il motivo e' l'uso di uno switch obsoleto all'interno del Makefile che si trova nella sottodirectory pam. Infatti la direttiva -strip-all non e' piu' riconosciuta dalle moderne versioni di GCC (il progetto Thinkfinger e' vecchiotto e non piu' aggiornato) ed impedisce il proseguimento della compilazione...si deve procedere editando a mano e cancellando --strip-all

di nuovo
make
make install

e finalmente abbiamo compilato ed installato Thinkfinger

per testarlo
si digita
luca@debian:~$ sudo tf-tool --acquire
a questo punto si deve far scivolare tre volte il dito sul sensore

ThinkFinger 0.2.2 (http://thinkfinger.sourceforge.net/) Copyright (C) 2006, 2007 Timo Hoenig <thoenig@suse.de> Initializing... done. Please swipe your finger (successful swipes 3/3, failed swipes: 0)... done. Storing data (/tmp/test.bir)... done.

per verificare il corretto funzionamento
luca@debian:~$ sudo tf-tool --verify
ThinkFinger 0.2.2 (http://thinkfinger.sourceforge.net/)
Copyright (C) 2006, 2007 Timo Hoenig <thoenig@suse.de>

Initializing... done.
Please swipe your finger (successful swipes 1/1, failed swipes: 0)... done. 
Result: Fingerprint does match. 

Non e' finita. Per usare il lettore delle impronte digitali come sistema di autenticazione al login si deve configurare Pam

lunedì 29 aprile 2013

Debian 64 bit vs 32 bit

Avendo a disposizione una Debian Box su un Centrino Duo mi sono lanciato nell'uso della Debian 64 bit

Da un certo punto di vista puo' essere utile utilizzare l'architettura a 64 quando si ha molta Ram (>4 Giga) da gestire (e non e' il mio caso) ma nell'uso quotidiano posso dire di non aver trovato particolari giovamenti se non qualche problema in piu'

Nel caso in cui si debba infatti eseguire un programma a 32 bit di cui non e' possibile ricompilare il sorgente e' necessario scaricare tutte le librerie sia in formato 64 bit che in formato 32 bit (i programmi e le librerie a cui sono linkati devono condividere la stessa architettura) con ovvie ripercussioni sull'uso dello spazio disco

Nel caso pratico si deve eseguire il comando

apt-get install ia32-libs ia32-libs-gtk
Un paio di casi di programmi per cui e' disponibile solo la versione a 32 bit sono per esempio Google Earth e Necessitas


La cosa divertente e' che se si tenda di lanciare una applicazione 32 bit  in un sistema a 64 bit, indipendentemente dalle flag di esecuzione, il sistema risponde che il programma non e' una applicazione

Debian Testing 64 Bit in IBM/Lenovo T61


L'ultimo arrivato nel mio parco macchina e' un IBM Lenovo T61 comprato usato ma in buone condizioni
Il sistema e' stato debianizzato con una Debian Testing 64 Bit (da ricordare che la versione 64 bit non e' quella denominata amd64 e non ia64)

L'installazione non ha mostrato nessun problema se non per un paio di dettagli
I driver della scheda di rete devono essere installati a parte aggiungendo i repository non-free e

apt-get install firmware-iwlwifi



L'altro aspetto che non funziona di default e' il lettore di impronte digitali per cui e' necessario installare ThinkFinger che e' descritto con maggiore dettaglio nel seguente post


Tv Digitale su Linux con HP Express Card EC 300

Grazie ad un regalo sono entrato in possesso di una scheda di acquisizione per il segnale della televisione digitale. La scheda, in formato PCI Express, era inclusa come dotazione di serie in Pavillion DV6000 (macchina particolarmente sfortunata per i problemi congeniti alla scheda video) e riporta sull'etichetta la dicitura DVB-T TV Tuner HP Express Card

Inserita nella mia Debian Box si vede che il chip risponde come un  DiBcom 3000MC/P e viene riconosciuto senza problemi dalla Debian Testing (la cosa curiosa e' che viene vista come una interfaccia USB)


Per fare funzionare la scheda e' necessario scaricare il programma aw_scan per la ricerca dei canali di digitale terrestre

apt-get install aw_scan

ed aggiornare il firmware digitando

cd /lib/firmware
wget http://www.linuxtv.org/downloads/firmware/dvb-usb-dibusb-6.0.0.8.fw
si puo' quindi iniziare la ricerca dei canali mediante il comando

w_scan -X -P -t 2 -E 0 -c IT > canali.txt
i risultati vengono salvati nel file testo canali.txt
e qui c'e' un piccolo trucco. Con l'antennina inclusa nella confezione non viene trovato nessuna canale, e' necessario, utilizzando l'adattatore, collegare la scheda all'antenna televisiva posta sul tetto

Collegamento con antenna condominiale

Dopo qualche minuto il file e' pronto e da VLC si seleziona
media/apri periferica
e si seleziona il file canali.txt

ed ecco il risultato finale



PCI Express su Lenovo/IBM T61

Su l'IBM/Lenovo T61 e' presente una PCI Express Card anche se e' piuttosto ben nascosta

Lo slot superiore di quello che sembra un comune ingresso PCMCIA e' infatti un ingresso Express Card per il fattore di forma piu' piccolo

Introducendo una scheda Pci Express in questo slot, questa scivola verso sinistra e trova il suo alloggiamento

Il tasto di estrazione e' caratterizzato da una X mentre il tasto di estrazione della PCMCIA ha un punto


Sostituire la Ram su IBM/Lenovo T61

Per sostituire/aggiornare la RAM su un IBM/Lenovo T61 si procede rimuovendo 4 viti al di sotto dello chassis del portatile indicate dall'icona della scheda di memoria

A questo punto si rovescia il computer e CON MOLTA PRUDENZA si solleva la scocca nella parte frontale. Particolare attenzione deve essere posta in questa operazione data la presenza del cavo flat che collega il trackpad e il lettore di impronte digitali




Sostituire la RAM su HP Compaq NX 7400

Per sostituire/aggiornare la RAM in un HP Compaq NX 7400 si procede prima di tutto rimuovendo le viti al di sotto del portatile con l'icona della RAM

Dopo si capovolge il computer e si liberano tre piccole clip presenti sulla tastiera facendo scivolare all'indietro la piccola slitta (nella foto il fermo che e' tra il tasto F4 ed F5)



A questo punto si procede sollevando la tastiera ed accedendo ad uno dei due slot di memoria (attenzione al cavo flat della tastiera!!!!)


Il secondo slot della Ram si trova in posizione molto piu' comoda al di sotto del portatile protetto da uno sporterllino fermato da una sola vite


lunedì 22 aprile 2013

ISS Spotting - 16 aprile 2013 22:37

Ho scoperto quasi per caso che dalla mia finestra e' possibile in questi giorni vedere comodamente il passaggio di ISS. Peraltro vi sono delle comodissime applicazioni Android che aiutano nell'individuazione del tempo e del punto in cui osservare

La prima impressione e' : ma quanto caspita e' veloce ISS?
La seconda e' la voglia di provare a fotografare il passaggio
Con una digitale compatta i risultati sono stati sconfortanti ed ho provato una Pentax K-m su cavalletto ed esposizione di 20 secondi

L'immagine e' scalata rispetto all'originale ed a mala pena si vede il puntino luminoso dell'ISS


Migliorando l'immagine si vede piu' chiaramente nel cerchio rosso la presenza di ISS


e questo e' l'ingrandimento

questa e' la schermata di Stellarium relativa al cielo durante l'osservazione


Non e' proprio dello stesso momento ma e' quantomeno curioso che mentre qualcuno sta a naso in su a vedere il passaggio di ISS qualche poco fortunato sta a naso in giu' a guardare la Terra



afsd

domenica 21 aprile 2013

Root su Nexus S I9023 con LInux

Le indicazioni di questo post derivano dai suggerimenti di questo link

Per ottenere i privilegi di root su un Nexus S esistono vari modi ed il piu' semplice e' usare il Nexus Root Toolkit ma questa soluzione funziona solo su Windows mentre io normalmente uso una Debian Box e quindi ho cercato strade che usino anche il sistema del pinguino


Per prima cosa si devono scaricare i file relativi ad una nuova recovery  (TeamWin Recovery)ed ai file per il rooting e si deve modificare il file android.rules

sudo gedit /etc/udev/rules.d/51-android.rules
sudo chmod 0644 /etc/udev/rules.d/51-android.rules---------------------------------------------------
# Google Nexus S
SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="4e21", MODE="0660", OWNER="luca" #Normal nexus s
SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="4e22", MODE="0660", OWNER="luca" #Debug & Recovery nexus s
SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="4e20", MODE="0660", OWNER="luca" #Fastboot nexus s
---------------------------------------------------
al termine dell'editazione si riavvia
/etc/init.d/udev restart

Di seguito si ritiene scontato avere l'SDK Android gia' montato

Sul sito di TeamWin c'e' un comodo motore di ricerca che seleziona il file per il proprio dispositivo..al momento io ho usato openrecovery-twrp-2.5.0.0-crespo.img mentre il rooting ho usato Superuser-3.1.3-arm-signed.zip.

Una volta scaricati i file si inserisce il Superuser sulla SDCard del telefono e si spenge il telefono e lo riavvia in fastboot mode (ovvero accendendo il telefono tenendo premuti Power e Vol +) e da linea di comando si digita

fastboot flash recovery openrecovery-twrp-2.5.9.0-crespo.img


al termine il terminale effettua un reboot
Si spenge di nuovo il terminale e si entra di nuovo in fastboot mode e stavolta si seleziona la voce di menu' Recovery (si usano i tasti del volume per salire e scendere ed il pusante di accensione per la conferma)
Il telefono si riavvia e si entra in Openrecovery
Si clicca su install e si seleziona Superuser-3.1.3-arm-signed.zip.
Si attende ed al nuovo riavvio il terminale e' sbloccato



sad

venerdì 19 aprile 2013

Root su GT-S7500

Le operazioni effettuate sono quelle indicate a questo link


Per prima cosa si deve mettere il telefono in Download Mode.
Da terminale spento si devono premere contemporaneamente i tasti Vol_Giu, Home ed Accensione

Una volta avviato si apre Odin e si collega il telefono via cavo
Si seleziona quindi il pulsante PDA ed il file recovery.zip



Si attende il termine delle operazioni ed il reboot del terminale

A questo punto essere un ottopode non e' necessario ma e' fortemente consigliato in quanto  il telefono deve essere riavviato un Recovery Mode ovvero (da telefono spento) si devono tenere premuti contemporaneamente i tasti Vol_Su, Vol_Giu, Home e Accensione (una volta avviato il telefono si puo' rilasciare l'accensione)

Si entra quindi in modalita' Recovery e si seleziona il file zip Superuser-3.1.3-arm-signed.zip.
Al termine delle operazioni si effettua l'ultimo reboot e si ha finalmente il controllo completo del terminale


d

adb no permissions in Linux

Nel cercare di connettere il Samsung GT-S7500 alla mia Debian Box mi sono scontrato contro il messaggio

adb no permissions


per risolvere il problema si deve diventare superutente (root) e digitare
adb kill-server
adb start-server

a questo punto si puo' ritornare sull'utente normale e si puo' interagire con il telefono

martedì 16 aprile 2013

Finestre a dimensione fissa in Qt

Per ottenere una finestra non ridimensionabile in Qt si puo' procedere settando questa proprieta'


this->setFixedSize(this->size());

DYI : cambiare le pastiglie del freno anteriore di un Kymco Agility ruote 12"

Si apre un nuovo settore di questo blog ovvero il fai-da-te non informatico.
In questo caso e' anche l'elogio della stupidita' perche' mi sono ritrovato a cambiare le pastiglie del freno quando oramai erano finite (frenando si sentiva chiaramente il fischio dell'attrito acciaio su acciaio)

La sostituzione e' piuttosto semplice in quanto necessita di due chiave ed un cacciavite ma come al solito le cose non vanno bene perche' 2 delle 4 viti sono risultate estremamente difficili da smontare

quindi conviene CON IL FRENO ANCORA MONTATO iniziare a svitare le due viti con testa  a brugola
Ad un certo punto non usciranno piu' perche' e' terminata la filettatura e si possono smontate tutto il blocco freno (senza rimuovere la ruota)




A questo punto si devono tirare con forza verso l'esterno le due viti con testa a brugola si liberano i pattini

Da notare l'usura del pattino usato, in alto, e quello nuovo in basso


s

Modificare il titolo di una finestra Qt

Per modificare il titolo di una finestra in Qt si procede con

this->setWindowTitle(QString);



lunedì 15 aprile 2013

Calcolare differenze di tempo in Qt

Di seguito un metodo semplice per calcolare la differenza in secondi tra due variabili QDateTime


---------------------------------------------------

#include "mainwindow.h"
#include "ui_mainwindow.h"

QDateTime ora;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ora = QDateTime::currentDateTime();
    ui->dateTimeEdit->setDateTime(ora);
    ui->label_ora->setText(ora.toString());


   }

MainWindow::~MainWindow()
{
    delete ui;
}



void MainWindow::on_pushButton_clicked()
{
    QDateTime partenza = ui->dateTimeEdit->dateTime();

    int diff = ora.secsTo(partenza);
    QString qStr = QString::number(diff);
    ui->label->setText("Diff.secondi : " +qStr);
}


---------------------------------------------------
Ancora Giove (in alto a destra) trionfa nel cielo invernale, stavolta insieme con la Luna ed Aldebaran

venerdì 12 aprile 2013

Dialog window modale e non modale in Qt

Di seguito un esempio su come aprire una finestra QDialog in modalita' modale e non modale (ovvero sempre in primo piano con focus attivo o meno)   


---------------------------------------------
   Dialog_class *dialog_class = new Dialog_class();
   dialog_class->setAttribute(Qt::WA_DeleteOnClose, true);
   
   //apre la finestra in modo modale
   dialog_class->exec();
   //apre la finestra in modo non modale
   dialog_class->show();
   dialog_class->raise();

Cancellare file in Qt

Un metodo per cancellare file in Qt
--------------------------------------------------------
void MainWindow::on_actionCancella_CVS_triggered()
{
    QFile file( QDir::homePath() + QDir::separator() +"anagrafiche_export.txt");
    if (file.exists())
    {
        file.remove();
    }
}

Aprire una porta UDP su un Firewall Linux

Un metodo rapido per aprire il firewall iptables di Linux per permettere le connessioni UDP sulla porta 55000


iptables -A INPUT -p udp --destination-port 55000 -j ACCEPT

Riportare al firmware originale Nexus S GT-I9023

Mi sono comprato usato un Nexus S GT-I9023.
Il telefono mi e' arrivato con una custom ROM con Android 4.2.2 ed ho deciso riportarlo al firmware originale di Google (un po' perche' mi sembrava un po' scattoso, un po' per avere la sicurezza di compatibilita')

La procedura e' quanto mai semplice:
Si scarica il firmware originale del telefono a questo indirizzo e si scompatta in una macchina con SDK Android installato (in realta' basta avere adb e fastboot)
Si riavvia il telefono in fastboot mode
Si lancia quindi (su Linux) lo script flash-all.sh
Gia' finito...bello avere un Nexus



Il telefono riavviato in Fastboot Mode


Il riavvio dopo aver flashato

Questi sono i messaggi a video, si osservi il tempo totale
----------------------------------------------------------------------
root@debianx40:/home/luca/Downloads/soju-jzo54k# ./flash-all.sh 
sending 'bootloader' (1536 KB)...
OKAY [  0.210s]
writing 'bootloader'...
OKAY [  0.382s]
finished. total time: 0.592s
rebooting into bootloader...
OKAY [  0.001s]
finished. total time: 0.001s
< waiting for device >
sending 'radio' (12288 KB)...
OKAY [  1.641s]
writing 'radio'...
OKAY [  1.903s]
finished. total time: 3.545s
rebooting into bootloader...
OKAY [  0.001s]
finished. total time: 0.001s
archive does not contain 'boot.sig'
archive does not contain 'recovery.sig'
archive does not contain 'system.sig'
--------------------------------------------
Bootloader Version...: I9020XXLC2
Baseband Version.....: I9020XXKI1
Serial Number........: 373342FC9C0400EC
--------------------------------------------
checking product...
OKAY [  0.001s]
checking version-bootloader...
OKAY [  0.001s]
checking version-baseband...
OKAY [  0.001s]
sending 'boot' (3964 KB)...
OKAY [  4.966s]
writing 'boot'...
OKAY [  0.563s]
sending 'recovery' (4308 KB)...
OKAY [  0.768s]
writing 'recovery'...
OKAY [  0.643s]
sending 'system' (337443 KB)...
OKAY [ 75.814s]
writing 'system'...
OKAY [ 42.327s]
erasing 'userdata'...
OKAY [  0.361s]
formatting 'userdata' partition...
Erase successful, but not automatically formatting.
Can't determine partition type.
OKAY [  0.015s]
erasing 'cache'...
OKAY [  1.690s]
formatting 'cache' partition...
Erase successful, but not automatically formatting.
Can't determine partition type.
OKAY [  0.001s]
rebooting...

finished. total time: 127.162s

martedì 9 aprile 2013

StrTok in Qt

Data una QString composta da piu' campi divisi da un separatore si possono ottenere le sottostringhe utilizzando un metodo differente da Strtok tipico di C ovvero passando attraverso una StringList
Nell'esempio che segue la stringa di input e' data da un pacchetto UDP cosi' formato

1;Luca;Innocenti

per ottenere il primo campo (il valore 1) si puo' procedere come segue

----------------------------------------------------------------------
QString pacchetto = datagram.data();




QStringList myStringList = pacchetto.split(";");
QString str_pettorale = myStringList.at(0);

----------------------------------------------------------------------
in pratica si preleva il primo campo (indice = 0) della StringList



Validare l'input di una QLineEdit

Per validare direttamente al momento della digitazione l'input in una QLineEdit di Qt si procede definendo prima un QRegExp con l'opportuna espressione regolare e poi si associa il validatore alla Line Edit

Piu' nel dettaglio


QRegExp re( "^[0-9]*$" );
QRegExpValidator *validator = new QRegExpValidator( re, 0 );
ui->linepettorale->setValidator( validator );

in questo modo nella QLineEdit denominata linepettorale saranno accettati solo valori numerici

Attenzione: questo metodo non funziona con i widget TextEdit

lunedì 8 aprile 2013

Sqlite Manager come estensione di Firefox

In ambiti in cui non e' possibile installare programmi puo' risultare utile utilizzare l'estensione SQLite Manager

L'installazione e' quella comune a tutti i plugin di Firefox e l'uso e' sostanzialmente immediato con la possibilita' di caricare il file ed eseguire query


venerdì 5 aprile 2013

Condividere variabili tra piu' classi (C++/Qt)

A causa dell'incapsulamento della programmazione ad oggetti non banale condividere dati tra piu' classi.

Un metodo per effettuare questa operazione e' quella di creare una classe apposita che gestisca le variabili con funzioni apposite per settare e recuperare il valore delle variabili

per esempio si puo' fare (chiamando la nuova classe variabili)
variabili.h
-----------------------------------------------------
#ifndef VARIABILI_H
#define VARIABILI_H

class variabili
{
public:
    variabili();
    void set_id(int id);
    int get_id();
private:
    static int m_int;
};

#endif // VARIABILI_H
-----------------------------------------------------

variabili.cpp
-----------------------------------------------------
#include "variabili.h"

int variabili::m_int;

variabili::variabili()
{

}
int variabili::get_id()
{
   return m_int;
}
void variabili::set_id(int id)
{
    m_int = id;
}
-----------------------------------------------------

per settare e leggere il valore della variabile condivisa nelle due classi si puo' operare come segue

Classe 1 (setta la variabile)
-----------------------------------------------------
#include <variabili.h>
.
.
.
variabili *myid = new variabili;
myid->set_id(2);
//int t1 = myid->get_id();
//qDebug() << "Main" << t1;
delete myid;
-----------------------------------------------------

Classe 2 (legge la variabile settata dalla Classe 1)
-----------------------------------------------------
#include <variabili.h>
.
.
.
variabili *myid = new variabili;
int t1 = myid->get_id();
//qDebug() << "Dialog" <<  t1;
delete myid;
-----------------------------------------------------

giovedì 4 aprile 2013

BitRock InstallBuilder

Un programma piu' complesso ma con le stesse funzionalita' di base di InstallJammer e' BitRock InstallBuilder

Il software e' a pagamento ma vengono rilasciate licence gratuite per progetti opensource



InstallJammer per Progetti Qt

Come indicato in questo post e' abbastanza semplice portare un programma Qt su una macchina diversa da quella di sviluppo in Windows

Si puo' migliorare creando un installer vero e proprio utilizzando il software InstallJammer, programma multipiattaforma per creare installer Qt

Attenzione: il progetto risulta dormiente o morto per cui non previsti sviluppi
Per Linux si puo' installare la versione 1.2.15 mentre per Windows e' necessario utilizzare la versione installjammer-1.2-snapshot.zip

Il programma e' piuttosto semplice



L'unica accortezza e' quella di includere nell'installer tutti i file indicati nel precedente post

martedì 2 aprile 2013

Settare il TabOrder in Qt

Per settare il tab order dei vari widget si deve aprire il menu Edit e selezionare Edit Tab Order
Il form cambiera' l'aspetto come in figura


Cliccando sui vari componenti si determinera' l'ordine con questi vengono attivati nel Tab Order.
C'e' da osservare che a differenza di Windows, in Qt il comportamento standard relativo al tasto Tab non e' quello di passare da un widget all'altro. Per ottenere questo comportamento si deve inserire la proprieta' tabChangesFocus su ogni componente



Configurare la TimeZone in Debian

UPDATE

Il metodo corretto e' digitare
dpkg-reconfigure tzdata

--------------------------------------------------

Per modificare la timezone della propria Linux Box si procede lanciando

tzselect


Per rendere la modifica permanente si deve modificare il proprio file .profile

Benchmark con Hardinfo

Di solito uso un paio di macchine, un Samsung N150 Plus ed un IBM X40, entrambi con una Debian Testing

E' da un po' di tempo che mi senbrava che il Centrino dell'X40 fosse piu' prestante del processore Atom N450 dell'N150 e per togliermi il dubbio ho provato ad usare hardinfo che si scarica semplicemente con

apt-get install hardinfo

il software, oltre a riconoscere l'hardware, permette di fare dei semplici benchmark del processore e di sotto riporto i risultati con il test BlowFish

 IBM X40

Samsung N150 Plus

E' abbastanza evidente che l'IBM, nonostante sia di circa 6 anni piu' vecchio, sia decisamente piu' veloce del Samsung. C'e' da dire che quando usci' l'X40 era un modello estremamente costoso e per professionisti mentre il Samsung e' da intendersi come un portatile per i poveri (infatti il primo lo ho comprato abbondantemente usato) e si puo' giustificare in parte la differenza ma gli anni a quanto pare sono passati invano

lunedì 1 aprile 2013

Errore su Grub Installer in MacPup 529

Cercando di riportare in vita una macchina obsoleta (e non volendo perdere troppo tempo con Debian) ho provato ad installare MacPup 529 con un Celeron 700 con circa 384 Mb di Ram

La distribuzione, fatta partire come LiveCd, mi ha ben impressionato riconoscendo tutto l'hardware compreso il SIS 630....i problemi sono nati quando ho deciso di passare all'installazione su disco fisso


Senza istruzioni e' quasi impossibile in quanto non e' prevista una procedura completa e decisamente non e' pensata per i principianti. Si devono effettuare tre passi distinti:
1) Partizionamento con GParted
2) Copia dei file con Puppy Universal Installer (nessun indice di progressione :<<<<)
3) Installazione Grub

Superati i due primi passi ci si accorge che, a causa di un bug, non e' possibile configurare Grub e si deve installare Grub4Dos come unica (e non documentata) soluzione

La distribuzione viene inoltre dichiarata compatibile con Ubuntu ma non vi e' traccia di apt-get quindi il supporto con Ubuntu e' quantomeno limitato

Anche la configurazione della scheda wireless (per quanto subito riconosciuta) non e' per niente intuitiva

In sostanza ho rimontato subito una Debian Squeeze che, pur facendo urlare per la prima ora di configurazione, funziona decisamente bene su una macchina obsoleta

Errore su Qt connectSlotsByName: No matching signal for ..

UPDATE
Ho risolto il problema e la soluzione come al solito e' sotto agli occhi.
In Windows avevo usato l'SDK completo (circa 770 Mb) scaricato dal sito di Qt con preinstallate le Qt 4.8.4 e con QtCreator 2.7
In Debian Wheezy avevo invece installato tutto mediante apt-get non vedendo che QtCreator era alla versione 2.5.Una volta aggiornato QtCreator anche su Linux tutto ha funzionato in modo corretto

---------------------------------------------------------

Spostando lo sviluppo di un progetto Qt da una macchina Windows ad una macchina Linux mi sono imbattuto in una cosa piuttosto curriosa



Il progetto si compila e funziona correttamente ma quando ho cercato di aggiungere una nuova entrata in QMenu al momento di compilare la menubar non risulta modificata ed viene segnalato l'errore

QMetaObject::connectSlotsByName: No matching signal for on_actionClassifica_triggered()

al momento non ho soluzioni per il problema

Zbar QRcode Scanner

Sulla base dell'esperienza di questo post sull'utilizzo della libreria zxing ha voluto provare la libreria ZBar piu' che altro per la necessita' di avere una maggiore velocita' di acquisizione

La principale differenza tra i due metodi e' che in Zxing si usa l'Intent ovvero si lancia una applicazione esterna e si attende il risultato mentre con ZBar si usa una libreria nativa inclusa nella propria applicazione


Il risultato e' una velocita' di elaborazione decisamente piu' veloce (ho dovuto creare una procedura apposita per impedire le acquisizione multiple su un stesso QrCode perche' il programma e' piu' veloce nel riconoscimento dello spostamento della mano)

Molto utile e' l'esempio compreso nella libreria che rende il tutto operativo in pochi minuti

Segue il codice di un programma che sto sviluppando per il riconoscimento dei pettorali delle corse podistiche
-----------------------------------------------------------------------

/*
 * Basic no frills app which integrates the ZBar barcode scanner with
 * the camera.
 * 
 * Created by lisah0 on 2012-02-24
 */
package net.sourceforge.zbar.android.CameraTest;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Timer;
import java.util.TimerTask;

import net.sourceforge.zbar.android.CameraTest.CameraPreview;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;

import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.Button;
import android.widget.Toast;

import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Size;

import android.widget.TextView;

/* Import ZBar Class files */
import net.sourceforge.zbar.ImageScanner;
import net.sourceforge.zbar.Image;
import net.sourceforge.zbar.Symbol;
import net.sourceforge.zbar.SymbolSet;
import net.sourceforge.zbar.Config;

public class CameraTestActivity extends Activity
{
    private Camera mCamera;
    private CameraPreview mPreview;
    private Handler autoFocusHandler;

    TextView scanText;
    Button scanButton;

    ImageScanner scanner;

    private boolean previewing = true;
private long partenza;
private String old_pettorale;
private String pettorale;
private TextView pett;
private EditText man;
private int contatore;


    static {
        System.loadLibrary("iconv");
    } 

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.main);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        contatore = 0;
        pettorale = "";
        
        autoFocusHandler = new Handler();
        mCamera = getCameraInstance();

        /* Instance barcode scanner */
        scanner = new ImageScanner();
        scanner.setConfig(0, Config.X_DENSITY, 3);
        scanner.setConfig(0, Config.Y_DENSITY, 3);

        mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
        FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
        preview.addView(mPreview);
        scanText = (TextView)findViewById(R.id.scanText);
        pett = (TextView)findViewById(R.id.pettorale);
        man = (EditText)findViewById(R.id.editText1);

        //gestisce l'introduzione manuale del pettorale
        man.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
                    //Log.d("test","Premuto il tasto Done");
                pettorale = man.getText().toString();
                    long attuale = System.currentTimeMillis();
                    long x = (attuale-partenza) / 1000;
          long seconds = x % 60;
          x /= 60;
          long minutes = x % 60;
          x /= 60;
          long hours = x % 24;
          x /= 24;
          long days = x;
          contatore = contatore + 1;
          String ora_passaggio = new SimpleDateFormat("HH:mm:ss dd/MM/yyyy").format(new Date(System.currentTimeMillis()));
          String race_time = String.format("%02d:%02d:%02d", hours,minutes,seconds);
          String str3 = Integer.toString(contatore)+";"+pettorale + ";" + race_time +"\n";
          pett.setText(str3);
         
     
          
          playAlarm();
          scrivi(ora_passaggio+";"+str3);
          send_udp(str3);
                    man.setText("");
                    old_pettorale=pettorale;
                    
                    }

// TODO Auto-generated method stub
return false;
}
});
        
    }

    public void onPause() {
        super.onPause();
        releaseCamera();
    }

    /** A safe way to get an instance of the Camera object. */
    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open();
        } catch (Exception e){
        }
        return c;
    }

    private void releaseCamera() {
        if (mCamera != null) {
            previewing = false;
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera = null;
        }
    }

    private Runnable doAutoFocus = new Runnable() {
            public void run() {
                if (previewing)
                    mCamera.autoFocus(autoFocusCB);
            }
        };

    PreviewCallback previewCb = new PreviewCallback() {
            private long attuale;
private String race_time;
private String ora_passaggio;
private String str3;
private String chk;

public void onPreviewFrame(byte[] data, Camera camera) {
                Camera.Parameters parameters = camera.getParameters();
                Size size = parameters.getPreviewSize();

                Image barcode = new Image(size.width, size.height, "Y800");
                barcode.setData(data);

                int result = scanner.scanImage(barcode);
                
                if ((result != 0) && (!start)) 
            {
            pett.setText("Partenza non effettuata");
            }
                
                if ((result != 0) && (start)) {
                    SymbolSet syms = scanner.getResults();
                    for (Symbol sym : syms) {
                        pettorale = sym.getData();        
                    }
                        attuale = System.currentTimeMillis();
                        if (!pettorale.equals(old_pettorale)) //evita le immissioni multiple di un pettorale
                       {
              long x = (attuale-partenza) / 1000;
          long seconds = x % 60;
          x /= 60;
          long minutes = x % 60;
          x /= 60;
          long hours = x % 24;
          x /= 24;
          long days = x;
          contatore = contatore + 1;
          chk ="Arrivo";
          race_time = String.format("%02d:%02d:%02d", hours,minutes,seconds);
          ora_passaggio = new SimpleDateFormat("HH:mm:ss dd/MM/yyyy").format(new Date(System.currentTimeMillis()));
          str3 =  Integer.toString(contatore)+";"+pettorale + ";" + race_time +"\n";
          pett.setText(str3);
          
          playAlarm();
          old_pettorale = pettorale;
          //pettorale = "";
          scrivi(ora_passaggio+";"+str3);
          send_udp(str3);
                   }
                        else
                        {// se il pettorale e' gia' stato battuto fai un suono differente
               //scanText.setText("Gia' acquisito");
                                               
                        }
                        
                        
        } //if result
            } // preview Frame
        }; //termina il callback
        
        
 private void playAlarm() {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
 }     
        

 private void scrivi(String testo)
{
File sdcard = Environment.getExternalStorageDirectory();
    if (sdcard.canWrite()) 
     {
     File localFile2 = new File(sdcard, "passaggi.txt");
         FileWriter localFileWriter1 = null;
 try {
localFileWriter1 = new FileWriter(localFile2, true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
 BufferedWriter localBufferedWriter = new BufferedWriter(localFileWriter1);
 try {
localBufferedWriter.write(testo);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
 try {
localBufferedWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
 }// chiude la scrittura su file
 }


 private void send_udp(String testo)
 {
DatagramSocket socket = null;
//testo = "luca";
try {
socket = new DatagramSocket();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
    InetAddress serverIP = null;
try {
serverIP = InetAddress.getByName("192.168.0.100");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
     byte[] outData = testo.getBytes();
     DatagramPacket out = new DatagramPacket(outData,outData.length, serverIP,55000);
     try {
socket.send(out);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
     socket.close();
 }

    public void onBackPressed() {
   new AlertDialog.Builder(this)
          .setMessage("Vuoi uscire?")
          .setCancelable(false)
          .setPositiveButton("Si", new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int id) {
                   finish();
              }
          })
          .setNegativeButton("No", null)
          .show();
}

    // Mimic continuous auto-focusing
    AutoFocusCallback autoFocusCB = new AutoFocusCallback() {
            public void onAutoFocus(boolean success, Camera camera) {
                autoFocusHandler.postDelayed(doAutoFocus, 1000);
            }
        };
private boolean start;
        
    @Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(1,1,0,"Partenza");
menu.add(1,2,1,"Annulla passaggio");
return true;
}
    
    public boolean onOptionsItemSelected(MenuItem item)
    {
    
switch(item.getItemId())
{
case 1:
if (!start) 
{
  start = true;
      partenza = System.currentTimeMillis();
      long x2 = (partenza) / 1000;
  long seconds2 = x2 % 60;
  x2 /= 60;
  long minutes2 = x2 % 60;
  x2 /= 60;
  long hours2 = x2 % 24;
  x2 /= 24;
  //long days = x;
      send_udp("Partenza   "+String.format("%02d:%02d:%02d", hours2,minutes2,seconds2));
          pett.setText("Partenza effettuata");
          scrivi("Partenza   "+String.format("%02d:%02d:%02d", hours2,minutes2,seconds2)+"\n");
          playAlarm();
}

else
{
Toast.makeText(this, "Partenza gia' effettuata",Toast.LENGTH_SHORT).show();
return false;
}


   Timer ti = new Timer();
   ti.scheduleAtFixedRate(new TimerTask() {
           public void run() {
            runOnUiThread(new Runnable() {
          private long attuale;
private String race_time;

@Override
          public void run() {
           //String tempo = new SimpleDateFormat("HH:mm:ss dd/MM/yyyy").format(new Date(System.currentTimeMillis()));
           if (partenza > 0)
           {
            attuale = System.currentTimeMillis();
    long x = (attuale-partenza) / 1000;
    long seconds = x % 60;
    x /= 60;
    long minutes = x % 60;
    x /= 60;
    long hours = x % 24;
    x /= 24;
    //long days = x;
    race_time = String.format("%02d:%02d:%02d", hours,minutes,seconds);
    scanText.setText(race_time);
           }
    }});}}, 0, 1000);
 //fa partire il cronometro della corsa
 partenza = System.currentTimeMillis();
   return true;
   
case 2:
send_udp("Annullato pettorale " + pettorale);
      pett.setText("Annullato pettorale " + pettorale);
      scrivi("Annullato pettorale " + pettorale+"\n");
      contatore = contatore - 1;
return true;

}

return false;
}
   
}