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;
}
   
}

Allineare i widgets in Qt

In condizioni normali se si ridimensiona una finestra Qt i widgets in essa contenuti non si dimensionano a loro volta con effetti grafici piuttosto sgradevoli

Per evitare questo effetto si puo' cliccare destro sul form e selezionare Layout/(...) per ottenere un ridimensionamento automatico


venerdì 29 marzo 2013

Sqlite Manager su Windows

Per gestire i file generati da Sqlite su Windows puo' essere utile usare il programma che si scarica gratuitamente da questo link


QTimer in Qt

Questo componente non visuale permette di gestire eventi a tempi predefiniti

La sintassi e' piuttosto semplice: si crea l'oggetto e si associa una funzione che viene richiamata ogni volta che l'oggetto genera un evento


Nell'esempio seguente gli eventi vengono generati ogni secondo
------------------------------------------

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();
    void TimerEvent();

private:
    Ui::MainWindow *ui;
    QTimer timer;
    unsigned contatore;
};

#endif // MAINWINDOW_H
------------------------------------------

------------------------------------------
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTimer>

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

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

void MainWindow::on_pushButton_clicked()
{
    contatore = 0;
    connect(&timer, SIGNAL(timeout()), this, SLOT(TimerEvent()));
    this->timer.start(1000);
}


void MainWindow::TimerEvent()
{
    contatore++;
    QString str;
    str.append(QString("%1").arg(contatore));
    ui->pushButton->setText(str);
    qDebug()<< contatore;
}
------------------------------------------

Importare Progetti Qt in QtCreator da Windows a Linux

Per poter spostare un progetto in Qt/QtCreator sviluppato su Windows in una Linux Box non e' sufficiente copiare la directory dei sorgenti in quanto una volta aperto il file .pro in QtCreator si avranno errori in particolare sul file Make

e' quindi necessario, prima di aprire il file .pro
1) Cancellare la directory di debug/release
2) Cancellare Makefile, Makefile.debug, Makefile.Release
3) cancella object_script*.*
4) cancellare il file *.pro.user (attenzione non file .pro)

a questo punto si puo' aprire il file .pro e compilare.
I file mancanti verranno ricostruiti sulla base delle impostazione Linux

(informazione ripresa da qui)

Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...