<?xml version="1.0" encoding="iso-8859-15"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"><channel><title>blogs.ASPItalia.com</title><link>http://blogs.aspitalia.com//az//</link><description>blogs.ASPItalia.com</description><language>it-it</language><copyright>1998-2013 ASPItalia.com/blogs.ASPItalia.com</copyright><generator>Generated by feed.ASPItalia.com 'Cortana' 2013.5.16</generator><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><sy:updateBase>1998-01-01T12:00+00:00</sy:updateBase><lastBuildDate>Sat, 02 Oct 2010 15:40:35 GMT</lastBuildDate><image><title>blogs.ASPItalia.com</title><url>http://gui.aspitalia.com/images/aspitalia/syndication.gif</url><link>http://blogs.aspitalia.com//az//</link></image><item><title>Installare Linux (Ubuntu) con PXE e Windows</title><link>http://blogs.aspitalia.com/az/post2657/Installare-Linux-Ubuntu-PXE-Windows.aspx</link><pubDate>Sat, 02 Oct 2010 15:40:35 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2657" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Per &lt;em&gt;memo&lt;/em&gt; scrivo questa esperienza. Tralascio cosa mi ha portato ad avere un portatile con il lettore CD non funzionante e senza la possibilità di &lt;em&gt;boot&lt;/em&gt; con USB sul quale dovevo installare come nuovo un sistema operativo. In mio soccorso è venuto a &lt;a title="Link esterno" href="http://it.wikipedia.org/wiki/Preboot_Execution_Environment"&gt;PXE&lt;/a&gt;, che permette l'avvio del computer via LAN da un server.&lt;/p&gt; &lt;p&gt;Su questo portatile è nata la necessità di installare Linux Ubuntu 9.10 - perché non la 10.04 o, aspettando qualche giorno, la 10.10? Che ne so: così dovevo.&lt;/p&gt; &lt;p&gt;Breve ricerca in Internet e trovo un tutorial che mi sembra utile:&lt;/p&gt; &lt;p&gt;&lt;a title="Link esterno" href="http://hugi.to/blog/archive/2006/12/23/ubuntu-pxe-install-via-windows"&gt;http://hugi.to/blog/archive/2006/12/23/ubuntu-pxe-install-via-windows&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Scarico TFTP Server e lo configuro come consigliato:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Creata la directory &lt;em&gt;tftp32&lt;/em&gt; in &lt;em&gt;C&lt;/em&gt;:&lt;/li&gt; &lt;li&gt;Copia dell'eseguibile &lt;em&gt;tftpd32&lt;/em&gt; scaricato direttamente dal suo &lt;a title="Link esterno" href="http://tftpd32.jounin.net/tftpd32_download.html"&gt;sito&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;Avvio e configurazione del programma nel seguente modo: &lt;br /&gt; &lt;br /&gt;&lt;img title="tftp32 configurazione" border="0" alt="tftp32 configurazione" src="http://blogs.aspitalia.com/img/andrewz/installarelinuxubuntuconpxeewindows_f316/ubuntu05_b504f11f-46ee-4977-b82b-8ec110e25e90.jpg" width="401" height="390" /&gt; &lt;br /&gt; &lt;br /&gt;Nel mio caso, la macchina è sulla porta 192.168.0.4 e il router risponde alla porta 192.168.0.1. Con &lt;em&gt;IP pool starting address&lt;/em&gt; ho inserito 192.168.0.9, in modo che il &lt;em&gt;DHCP&lt;/em&gt; di questo tool assegnasse alle macchine collegate da questo indirizzo in poi.&lt;/li&gt; &lt;li&gt;Dai server di Ubuntu ho &lt;a title="Link esterno" href="ftp://archive.ubuntu.com/ubuntu/dists/karmic/main/installer-i386/current/images/netboot/"&gt;scaricato&lt;/a&gt; il file &lt;em&gt;netboot.tar.gz&lt;/em&gt;. Con il programma &lt;a title="Link esterno" href="http://www.7-zip.org/"&gt;7-Zip&lt;/a&gt; lo decompresso in &lt;em&gt;C:\tftp32&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;Da questa directory ho cancellato i file: &lt;em&gt;pxelinux.cfg&lt;/em&gt; e &lt;em&gt;pxelinux.0&lt;/em&gt;, quindi dalla directory ubuntu-installer\i386 ho copiato la sottostante directory &lt;em&gt;pxelinux.cfg&lt;/em&gt; in &lt;em&gt;C:\tftp32&lt;/em&gt;, così come il file &lt;em&gt;pxelinux.0&lt;/em&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Con il programma &lt;em&gt;tftpd32&lt;/em&gt; in esecuzione, avvio il portatile che riconosce e raggiunge il mio server PXE e appare la prima schermata dove seleziono l'installazione del sistema operativo. Dopo pochi secondi il portatile riporta un errore e non va oltre. Guardando nel LOG di &lt;em&gt;Tftpd Server&lt;/em&gt; vedo questo messaggio:&lt;/p&gt; &lt;p&gt;&lt;em&gt;File &amp;lt;ubuntu-installer\i386\linux&amp;gt; : error 131 in system call ReadFile An attempt was made to move the file pointer before the beginning of the file.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Faccio una nuova ricerca in Internet e trovo che questo problema è comune a molti utenti. Per mio svago inutile prendo i file suggeriti in quel tutorial anche da versioni precedenti di Ubuntu, ma l'errore persiste. Vado oltre, e provo a modificare, senza cognizione di causa, le opzioni di TFTP Server ma sono ancora frustrato per il fallimento.&lt;/p&gt; &lt;p&gt;In un attimo di lucidità arrivo a queste conclusioni:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Il portatile non ha problemi se non il lettore CD, non è il suo PXE ad avere problemi.&lt;/li&gt; &lt;li&gt;Il file &lt;em&gt;linux&lt;/em&gt; non è corrotto visto che l'ho preso anche quello di altre versioni.&lt;/li&gt; &lt;li&gt;Il problema sta in tftpd32.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Cerco un altro client per il TFTP, e trovo &lt;a title="Link esterno" href="http://www.winagents.com/en/products/tftp-client/index.php"&gt;WinAgents TFTP server&lt;/a&gt;. Scarico e installo. Avvio e sembra che non ci siano problemi. Pecco d'ingenuità riavviando il portatile vedendo che non esegue il boot grazie a PXE. Il problema è che quest'ultimo software non ha un DHCP in grado di assegnare un indirizzo alla macchina. Dopo dodici secondi di smarrimento torno a tftpd32 e tra le opzioni vedo che posso avviare solo il DHCP lasciando spento il server TFTP nei &lt;em&gt;settings&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;img title="Settings tftpd32" border="0" alt="Settings tftpd32" src="http://blogs.aspitalia.com/img/andrewz/installarelinuxubuntuconpxeewindows_f316/image_dec40af0-95e8-4bc4-8c8f-f62f6bc18235.png" width="363" height="530" /&gt; &lt;/p&gt; &lt;p&gt;Entrambi i programmi sono avviati e avvio anche il portatile. Nel log del programma TFTP vedo che ora funziona tutto correttamente:&lt;/p&gt; &lt;p&gt;&lt;img title="ubuntu2" border="0" alt="ubuntu2" src="http://blogs.aspitalia.com/img/andrewz/installarelinuxubuntuconpxeewindows_f316/ubuntu2_5f40a6d0-5442-4202-8f9b-909c025985d9.jpg" width="520" height="337" /&gt; &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Conferma viene dal portatile che mostra le varie fasi di configurazione e avvia la fase di installazione correttamente: tutto viene installato da Internet e mi ritrovo dopo molto tempo con il portatile installato con gli ultimi aggiornamenti disponibili per quel quella distribuzione.&lt;/p&gt; &lt;p&gt;Un modo come un altro per passare il sabato pomeriggio. Cosa altro avevo da fare visto che in bicicletta ero andato questa mattina? E poi non avevo mai fatto installazioni di sistemi operativi su PC da &lt;em&gt;ethernet&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Off_Topic/" rel="tag"&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2657/Installare-Linux-Ubuntu-PXE-Windows.aspx"&gt;&lt;em&gt;Installare Linux (Ubuntu) con PXE e Windows&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Linux, Off Topic</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2657/Installare-Linux-Ubuntu-PXE-Windows.aspx</guid><slash:comments>3</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2657/Installare-Linux-Ubuntu-PXE-Windows.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2657.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2657</trackback:ping></item><item><title>Format date e format number con jquery</title><link>http://blogs.aspitalia.com/az/post2650/Format-Date-Format-Number-Jquery.aspx</link><pubDate>Tue, 10 Aug 2010 18:42:17 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2650" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Il cosiddetto &lt;em&gt;web 2.0&lt;/em&gt;, parolona per definire ciò che è possibile da anni e che fa tanto esperti, dovrebbe migliorare l'interattività di un sito web con il suo utilizzatore - ma ha ancora senso definirlo sito web o ormai si può definire a tutti gli effetti applicativi web? Quesito la cui risposta ha lo stesso senso della domanda per me: inutile.&lt;/p&gt; &lt;p&gt;L'interattività grazie a tecnologie come &lt;em&gt;ajax&lt;/em&gt; permette la fruizione del contenuto di un sito web, nella volontà del progettista del sito, in modo migliore. &lt;em&gt;Javascript&lt;/em&gt; fa la parte da leone e il vero e proprio avvento di &lt;em&gt;&lt;a title="Link esterno" href="http://jquery.com/"&gt;jQuery&lt;/a&gt;&lt;/em&gt; ha aiutato la programmazione con questo linguaggio/tecnologia. E' innegabile: grazie a &lt;em&gt;jQuery&lt;/em&gt; la scrittura del codice &lt;em&gt;javascript&lt;/em&gt; è più agevole, una volta capita la sua base, e permette un'ottima compatibilità tra i vari &lt;em&gt;browser&lt;/em&gt; e il sempre meno ultimo ritocco e test dovuti a funzionalità non compatibili tra i vari &lt;em&gt;browser&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Nelle settimane scorse alla ricerca di un &lt;em&gt;plug-in&lt;/em&gt; per &lt;em&gt;jQuery&lt;/em&gt; che permettesse la trattazione di numeri e date nel modo più agevole e .&lt;em&gt;net&lt;/em&gt; compatibile, mi è stato consigliato &lt;a title="Link esterno" href="http://www.asual.com/jquery/format/"&gt;questo&lt;/a&gt; (link dove si può scaricare anche un esempio per capire le varie funzionalità).&lt;/p&gt; &lt;p&gt;Vediamo un semplice esempio sul suo utilizzo. Ecco il codice &lt;em&gt;html&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;em&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;&lt;/em&gt;&lt;a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;"&gt;&lt;em&gt;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&amp;gt; &lt;br /&gt;&amp;lt;html xmlns=&amp;quot;&lt;/em&gt;&lt;a href="http://www.w3.org/1999/xhtml&amp;quot;"&gt;&lt;em&gt;http://www.w3.org/1999/xhtml&amp;quot;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&amp;gt; &lt;br /&gt;&amp;lt;head&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;title&amp;gt;Test number format&amp;lt;/title&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script src=&amp;quot;jquery-1.4.2.min.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script src=&amp;quot;jquery.format-1.0.min.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(document).ready(function() { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var d = new Date(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var df = $.format.date(d, 'dd/MM/yyyy'); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&amp;quot;#msg1&amp;quot;).html(df);&amp;#160; &lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var borndate = &amp;quot;02-26-1974&amp;quot;; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var df2 = $.format.date(borndate, 'MM-dd-yyyy'); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&amp;quot;#msg2&amp;quot;).html(df2.toString());&amp;#160; &lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var value = 1234.56; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&amp;quot;#msg3&amp;quot;).html($.format.number(value, '#,##0.00')); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&amp;quot;#msg4&amp;quot;).html($.format.number(value, '#.##0,00')); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&amp;quot;#msg5&amp;quot;).html($.format.number('1234.56'));&amp;#160; &lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $.format.locale({ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; number: { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; groupingSeparator: '.', &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; decimalSeparator: ',' &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }); &lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&amp;quot;#msg6&amp;quot;).html($.format.number(value, '#,##0.00')); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&amp;quot;#msg7&amp;quot;).html($.format.number(value, '#.##0,00'));&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/script&amp;gt; &lt;br /&gt;&amp;lt;/head&amp;gt; &lt;br /&gt;&amp;lt;body&amp;gt; &lt;br /&gt;&amp;lt;div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;h1&amp;gt;Date&amp;lt;/h1&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span&amp;gt;Visualizza data nel formato dd/MM/yyyy:&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span id=&amp;quot;msg1&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span&amp;gt;Converte stringa in data dal formato MM-dd-yyyy:&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span id=&amp;quot;msg2&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;h1&amp;gt;Number&amp;lt;/h1&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span&amp;gt;Visualizzo numero 1234.56 nel formato #,##0.00:&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span id=&amp;quot;msg3&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span&amp;gt;Visualizzo numero 1234.56 nel formato #.##0,00:&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span id=&amp;quot;msg4&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span&amp;gt;Converto stringa in numero (esempio 1234.56):&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span id=&amp;quot;msg5&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span&amp;gt;Visualizzo numero 1234.56 nel formato #,##0.00 (dopo aver modificato i separatori):&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span id=&amp;quot;msg6&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span&amp;gt;Visualizzo numero 1234.56 nel formato #.##0,00 (dopo aver modificato i separatori):&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span id=&amp;quot;msg7&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;/body&amp;gt; &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;In esso ho messo tutti gli esempi di base che possono capitare:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Da data a stringa nel formato voluto - per esempio dd/MM/yyyy.&lt;/li&gt; &lt;li&gt;Da stringa a data - per esempio, da MM-dd-yyyy&lt;/li&gt; &lt;li&gt;Numero a stringa nel formato voluto - per esempio #,##0.00.&lt;/li&gt; &lt;li&gt;Conversione da stringa a numero&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;L'output del codice qui sopra è il seguente:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Date&lt;/strong&gt; &lt;br /&gt;Visualizza data nel formato dd/MM/yyyy: 10/08/2010 &lt;br /&gt;Converte stringa in data dal formato MM-dd-yyyy: Tue Feb 26 1974 20:23:55 GMT+0100 (ora solare Europa occidentale) &lt;br /&gt;&lt;strong&gt;Number&lt;/strong&gt; &lt;br /&gt;Visualizzo numero 1234.56 nel formato #,##0.00: 1,234.56 &lt;br /&gt;Visualizzo numero 1234.56 nel formato #.##0,00: 1234.5600 &lt;br /&gt;Converto stringa in numero (esempio 1234.56): 1234.56 &lt;br /&gt;Visualizzo numero 1234.56 nel formato #,##0.00 (dopo aver modificato i separatori): 1.234,56 &lt;br /&gt;Visualizzo numero 1234.56 nel formato #.##0,00 (dopo aver modificato i separatori): 1234,5600&lt;/p&gt; &lt;p&gt;Ok, ho detto tutto quello che volevo dire. anzi no, ma del resto chi vuoi che qualcuno se ne interessi? Ah giusto, è più importante l'esordio della nazionale di Prandelli con il Costa d'Avorio.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/JavaScript/" rel="tag"&gt;JavaScript&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2650/Format-Date-Format-Number-Jquery.aspx"&gt;&lt;em&gt;Format date e format number con jquery&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Software, JavaScript</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2650/Format-Date-Format-Number-Jquery.aspx</guid><slash:comments>2</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2650/Format-Date-Format-Number-Jquery.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2650.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2650</trackback:ping></item><item><title>Come si fa a procurarsi un alibi con le webcam (C#/C++/Qt)</title><link>http://blogs.aspitalia.com/az/post2649/FA-Procurarsi-Alibi-Webcam-CSharp-C-QT.aspx</link><pubDate>Mon, 09 Aug 2010 18:13:37 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2649" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Dopo che ho inserito, in quell'ammasso di inutilità che è Facabook, una fotografia dove venivo immortalato da una webcam della mia zona mentre ero in bici, una persona, che invece di godersi le ferie e farsi un po' di fatti suoi, mi ha chiesto come avessi fatto.&lt;/p&gt; &lt;p&gt;Innanzitutto non ero d'accordo con nessuno. Ho banalmente scritto un software che ogni &lt;em&gt;n&lt;/em&gt; minuti cattura l'immagine di una webcam pubblica e la salva su disco. Prima di partire in bici ho avviato il programmino e al mio ritorno mi sono trovato su disco un centinaio di immagini con quella in cui mi procuravo l'alibi per ieri pomeriggio. Per semplice curiosità, ecco l'immagine catturata (ridotta):&lt;/p&gt; &lt;p&gt;&lt;img title="Webcam in valle camonica" border="0" alt="Webcam in valle camonica" src="http://blogs.aspitalia.com/img/andrewz/comesifaaprocurarsiunalibiconlewebcamccq_114e2/20100808140601_mini_a32f7975-75d7-44c1-8cd8-90610a9ff142.jpg" width="451" height="338" /&gt; &lt;/p&gt; &lt;p&gt;Ovviamente sono poco distinguibile e in un processo non mi basterebbe per evitare la forca. Il software lo avevo scritto in due linguaggi di programmazione: in C# con il &lt;a title="Link esterno" href="http://it.wikipedia.org/wiki/Framework_.NET"&gt;Framework .Net&lt;/a&gt; di Microsoft, e in C++ con il &lt;a title="Link esterno" href="http://it.wikipedia.org/wiki/Qt_%28toolkit%29"&gt;toolkit Qt&lt;/a&gt;. Per semplicità di codice e velocità di realizzazione non c'è paragone ovviamente e l'ago della bilancia si volge verso il C#. Vediamo il codice con questa tecnologia:&lt;/p&gt; &lt;p&gt;&lt;em&gt;using System; &lt;br /&gt;using System.Collections.Generic; &lt;br /&gt;using System.Linq; &lt;br /&gt;using System.Text; &lt;br /&gt;using System.IO; &lt;br /&gt;using System.Net; &lt;br /&gt;using System.Timers; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;namespace WebCam &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; class Program &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private static System.Timers.Timer _t; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; const string url ="xxx"&lt;/em&gt;&lt;em&gt;;&lt;/em&gt; // Url dell'immagine della webcam &lt;br /&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; static void Main(string[] args) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Directory.CreateDirectory(Path.Combine( &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AppDomain.CurrentDomain.BaseDirectory, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;photo&amp;quot; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; )); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _t = new System.Timers.Timer(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _t.AutoReset = false; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _t.Interval = CalcolaIntervallo(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _t.Elapsed += new ElapsedEventHandler(TakePhoto); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _t.Start(); &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.Write(&amp;quot;Press 'enter' to exit... &amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.ReadLine(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _t.Stop(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; static void TakePhoto(object sender, ElapsedEventArgs e) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Drawing.Image imagesource; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Stream str = null; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; try &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create(url); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; HttpWebResponse wRes = (HttpWebResponse)(wReq).GetResponse(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; str = wRes.GetResponseStream(); &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; imagesource = System.Drawing.Image.FromStream(str); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; imagesource.Save(Path.Combine( &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AppDomain.CurrentDomain.BaseDirectory, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;photo/&amp;quot; + &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DateTime.Now.ToString(&amp;quot;yyyyMMddHHmmss&amp;quot;) + &amp;quot;.jpg&amp;quot;)); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; catch { } &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _t.Interval = GetIntervall(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _t.Start(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private static double GetIntervall() &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DateTime next_date = DateTime.Now; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; next_date = new DateTime(next_date.Year, next_date.Month, next_date.Day, next_date.Hour, next_date.Minute, 0).AddMinutes(1); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TimeSpan diff = next_date.Subtract(DateTime.Now); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return diff.Ticks / 10000; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Questa &lt;em&gt;console application&lt;/em&gt; si basa su un timer che ogni minuto esegue il codice della funzione &lt;em&gt;TakePhoto&lt;/em&gt; che con una WebRequest si salva in locale l'immagine del server remoto. Quindi ricalcola quanto tempo dopo il timer deve &lt;em&gt;scattare&lt;/em&gt; nuovamente per la prossima immagine.&lt;/p&gt; &lt;p&gt;Le cose con il &lt;em&gt;C++&lt;/em&gt; si complicano, ovviamente anche se il toolkit Qt aiuta molto. Utilizzando gli oggetti di Qt sono obbligato ad utilizzare le sue regole, e scegliendo come tipo di applicativo la &lt;em&gt;console application&lt;/em&gt; sono obbligato a utilizzare il &lt;em&gt;QCoreApplication&lt;/em&gt; in modo che da poter gestire gli eventi; inizialmente il suo utilizzo comporta delle piccole adattazioni visto che dobbiamo creare una classe che comunichi con esso utilizzando sempre gli eventi. Ecco il corpo del file principale &lt;em&gt;main.cpp&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;em&gt;#include &amp;lt;QObject&amp;gt; &lt;br /&gt;#include &amp;lt;QtCore/QCoreApplication&amp;gt; &lt;br /&gt;#include &amp;lt;QTimer&amp;gt; &lt;br /&gt;#include &amp;quot;webcam.h&amp;quot; &lt;br /&gt;#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;int main(int argc, char *argv[]) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QCoreApplication a(argc, argv);&amp;#160; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; webcam wc; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QObject::connect(&amp;amp;wc, SIGNAL( done() ), &amp;amp;a, SLOT( quit() ), Qt::QueuedConnection); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QTimer::singleShot(0, &amp;amp;wc, SLOT( takePhoto() )); &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; return a.exec(); &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;p&gt;La gestione degli eventi viene implementata grazie ai &lt;em&gt;SIGNAL&lt;/em&gt; e &lt;em&gt;SLOT&lt;/em&gt;. In questo mio &lt;a title="Link esterno" href="http://blogs.aspitalia.com/az/post2617/QtCreator.aspx"&gt;post&lt;/a&gt; ne spiego a grandi linee il funzionamento. Dopo la dichiarazione dell'oggetto &lt;em&gt;webcam&lt;/em&gt; collego il suo &lt;em&gt;signal done&lt;/em&gt; con lo &lt;em&gt;slot quit&lt;/em&gt; del &lt;em&gt;QCoreApplication&lt;/em&gt;. Dopo il collegamento con il &lt;em&gt;QTimer&lt;/em&gt; si avvia la funzione principale di &lt;em&gt;webcam&lt;/em&gt;, &lt;em&gt;takePhoto&lt;/em&gt; che sarà spiegato dopo. Questo permette di uscire correttamente dal programma alla fine dell'esecuzione della procedura &lt;em&gt;takePhoto&lt;/em&gt; in &lt;em&gt;webcam&lt;/em&gt;. Ulteriori informazioni si possono trovare &lt;a title="Link esterno" href="http://qt-mobility.blogspot.com/2009/12/create-hello-world-console-application.html"&gt;qui&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Ecco i due file della classe &lt;em&gt;webcam&lt;/em&gt; il primo &lt;em&gt;webcam.h&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;em&gt;#ifndef WEBCAM_H &lt;br /&gt;#define WEBCAM_H &lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;#include &amp;lt;QObject&amp;gt; &lt;br /&gt;#include &amp;lt;stdio.h&amp;gt; &lt;br /&gt;#include &amp;lt;iostream&amp;gt; &lt;br /&gt;#include &amp;lt;qtextstream.h&amp;gt; &lt;br /&gt;#include &amp;lt;qtimer.h&amp;gt; &lt;br /&gt;#include &amp;lt;qnetworkaccessmanager.h&amp;gt; &lt;br /&gt;#include &amp;lt;qnetworkrequest.h&amp;gt; &lt;br /&gt;#include &amp;lt;qnetworkreply.h&amp;gt; &lt;br /&gt;#include &amp;lt;qfile.h&amp;gt; &lt;br /&gt;#include &amp;lt;qurl.h&amp;gt; &lt;br /&gt;#include &amp;lt;qeventloop.h&amp;gt; &lt;br /&gt;#include &amp;lt;qdatetime.h&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;#include &amp;quot;thread.h&amp;quot; &lt;br /&gt;using namespace std; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;class webcam : public QObject &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Q_OBJECT &lt;br /&gt;public: &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; explicit webcam(QObject *parent = 0); &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;signals: &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void done(); &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;public slots: &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void takePhoto(); &lt;br /&gt;}; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;#endif // HELLOWORLD_H&lt;/em&gt;&lt;/p&gt; &lt;p&gt;E il file &lt;em&gt;webcam.cpp&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;em&gt;#include &amp;quot;webcam.h&amp;quot; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;webcam::webcam(QObject *parent) : &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QObject(parent) &lt;br /&gt;{ &lt;br /&gt;} &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;void webcam::takePhoto() { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Thread *th=new Thread; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; th-&amp;gt;start(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; cout &amp;lt;&amp;lt; &amp;quot;Press 'enter' to exit... &amp;quot;; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QTextStream qtin(stdin); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QString line = qtin.readLine(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; //th-&amp;gt;terminate(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; th-&amp;gt;stop(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; th-&amp;gt;wait(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; delete th; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; done(); &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;p&gt;La funzione &lt;em&gt;takePhoto&lt;/em&gt; istanzia la classe &lt;em&gt;thread. &lt;/em&gt;Questa deriva dalla classe QThread e permette di creare un &lt;em&gt;thread&lt;/em&gt; parallelo che sarà utilizzato per il download dell'immagine della webcam, &lt;em&gt;thread&lt;/em&gt; avviato richiamando la sua funzione &lt;em&gt;start&lt;/em&gt;. Quindi scrive nel &lt;em&gt;terminal&lt;/em&gt; il messaggio che spiega come terminare il programma e aspetta la pressione del tasto &lt;em&gt;enter&lt;/em&gt; prima di distruggere i vari oggetti e richiamato il signal &lt;em&gt;done&lt;/em&gt; che, come si ricorderà, essendo collegato all'oggetto &lt;em&gt;QCoreApplication&lt;/em&gt;, chiuderà il programma correttamente.&lt;/p&gt; &lt;p&gt;Non rimane che vedere la classe &lt;em&gt;thread&lt;/em&gt;. Ecco il file &lt;em&gt;thread.h&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;em&gt;#ifndef THREAD_H &lt;br /&gt;#define THREAD_H &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;#include &amp;lt;QObject&amp;gt; &lt;br /&gt;#include &amp;lt;QThread&amp;gt; &lt;br /&gt;#include &amp;lt;QDateTime&amp;gt; &lt;br /&gt;#include &amp;lt;QUrl&amp;gt; &lt;br /&gt;#include &amp;lt;QNetworkRequest&amp;gt; &lt;br /&gt;#include &amp;lt;QNetworkAccessManager&amp;gt; &lt;br /&gt;#include &amp;lt;QEventLoop&amp;gt; &lt;br /&gt;#include &amp;lt;QNetworkReply&amp;gt; &lt;br /&gt;#include &amp;lt;QFile&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;class Thread : public QThread &lt;br /&gt;{ &lt;br /&gt;Q_OBJECT &lt;br /&gt;public: &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; explicit Thread(QObject *parent = 0); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; void stop(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; virtual void run(); &lt;br /&gt;&lt;/em&gt;&lt;em&gt;protected: &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; int getInterval(); &lt;br /&gt;&lt;/em&gt;&lt;em&gt;private: &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QString messageStr; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; volatile bool stopped; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;signals: &lt;br /&gt;&lt;/em&gt;&lt;em&gt;public slots: &lt;br /&gt;&lt;/em&gt;&lt;em&gt;}; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;#endif // THREAD_H&lt;/em&gt;&lt;/p&gt; &lt;p&gt;E il file &lt;em&gt;thread.cpp&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;em&gt;#include &amp;quot;thread.h&amp;quot; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;Thread::Thread(QObject *parent) : &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QThread(parent) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; stopped=false; &lt;br /&gt;} &lt;br /&gt;void Thread::stop() &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; stopped = true; &lt;br /&gt;} &lt;br /&gt;void Thread::run() &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; while (!stopped) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; QUrl url("xx"&lt;/em&gt;&lt;em&gt;);&lt;/em&gt; // url della webcam &lt;br /&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; QNetworkRequest request(url); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; QNetworkAccessManager manager; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; QEventLoop loop; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; QNetworkReply *reply = manager.get( request ); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; QObject::connect(reply, SIGNAL(finished()), &amp;amp;loop, SLOT(quit())); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; loop.exec(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; QFile file(&amp;quot;./&amp;quot; + QDateTime::currentDateTime().toString(&amp;quot;yyyyMMddHHmmss&amp;quot;)+&amp;quot;.jpg&amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.open(QIODevice::WriteOnly); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.write(reply-&amp;gt;readAll()); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; file.close(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delete reply;&amp;#160; &lt;br /&gt; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; QThread::sleep(getInterval()); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //QThread::sleep(10); // only for test &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;} &lt;br /&gt;int Thread::getInterval() &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QDateTime dt=QDateTime::currentDateTime(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QString qq=dt.toString(&amp;quot;yyyy, MM, dd, HH, mm, 00&amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; QDateTime dt2=QDateTime::fromString(qq,&amp;quot;yyyy, MM, dd, HH, mm, ss&amp;quot;).addSecs(60); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return dt.secsTo(dt2); &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Il funzionamento è molto differente con quello scritto in &lt;em&gt;C#&lt;/em&gt;: prima veniva utilizzato il timer per l'attesa tra il download dell'immagine, qui un &lt;em&gt;thread&lt;/em&gt; che girando continuamente calcola quanto la funzione &lt;em&gt;sleep&lt;/em&gt; deve &lt;em&gt;addormentare&lt;/em&gt; il &lt;em&gt;thread&lt;/em&gt; prima del nuovo download dell'immagine.&lt;/p&gt; &lt;p&gt;La versione in &lt;em&gt;C++&lt;/em&gt; non è proprio perfetta perché alla pressione del tasto &lt;em&gt;enter&lt;/em&gt;, prima di chiudere il programma, attende la fine dello &lt;em&gt;sleep&lt;/em&gt; della procedura. La cosa si può risolvere con poche righe di codice di controllo, ma il programmino funzionava bene anche così e non avevo alcuna pretesa di perfezione dello stesso viste le mie conoscenza limitate del &lt;em&gt;toolkit Qt&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;La salita è questa: &lt;a title="Link esterno" href="http://www.zanibike.net/camonica/salita_del_beato.aspx"&gt;link&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/.NET_Framework/" rel="tag"&gt;.NET Framework&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2649/FA-Procurarsi-Alibi-Webcam-CSharp-C-QT.aspx"&gt;&lt;em&gt;Come si fa a procurarsi un alibi con le webcam (C#/C++/Qt)&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Software, .NET Framework</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2649/FA-Procurarsi-Alibi-Webcam-CSharp-C-QT.aspx</guid><slash:comments>0</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2649/FA-Procurarsi-Alibi-Webcam-CSharp-C-QT.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2649.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2649</trackback:ping></item><item><title>3D multipiattaforma con QT e Irrlicht</title><link>http://blogs.aspitalia.com/az/post2633/3D-Multipiattaforma-QT-Irrlicht.aspx</link><pubDate>Wed, 02 Jun 2010 14:00:00 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2633" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Una persona leggendo il mio &lt;a title="link mio blog precedente" href="http://blogs.aspitalia.com/az/post2617/QtCreator.aspx"&gt;blog precedente&lt;/a&gt; mi ha chiesto informazioni a riguardo di un&amp;#8217;immagine inserita come esempio in cui si vedeva una interfaccia tradizionale e una immagine 3D con il logo di &lt;em&gt;Irrlicht&lt;/em&gt;. Questa:&lt;/p&gt;

&lt;p&gt;&lt;img alt="Esempio di interfaccia grafica in QtCreator" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/image_c09ed4f4-6875-40e2-ae07-dd355288e69d.png" width="520" height="470" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a title="Link esterno" href="http://irrlicht.sourceforge.net/"&gt;Irrlicht&lt;/a&gt; è un progetto nato nei primi anni di questo millennio. Permette la creazione di ambienti 2D/3D sfruttando l&amp;#8217;accelerazione 3D con l&amp;#8217;uso di &lt;em&gt;DirectX&lt;/em&gt; e &lt;em&gt;OpenGL&lt;/em&gt;. Altro pregio di non poco conto è la sua disponibilità&amp;#160; per molte piattaforme: &lt;em&gt;Windows&lt;/em&gt;, &lt;em&gt;Linux&lt;/em&gt; e &lt;em&gt;Mac&lt;/em&gt;. Inoltre &lt;em&gt;Irrlicht&lt;/em&gt; supporta una marea di formati file: 3ds Max files, Quake 2 MD2 Models, Maya .obj objects, Quake 3 .bsp maps, Milkshape3D objects, DirectX .x files... Per altri formati 3D sono presenti molti &lt;em&gt;plugins&lt;/em&gt;. Inoltre è presente tutto quanto può essere utile per la creazione di un'ambientazione 3D: luci (con nebbia e riflessi), posizione delle camere, animazioni. E' possibile creare ambienti 3D esterni con il rendering del terreno, sia di ambienti interni e molto altro. Conobbi questo progetto alcuni anni fa, quando era presente anche una versione per il suo utilizzo con il &lt;em&gt;Framework .NET&lt;/em&gt;: purtroppo questo supporto è stato cancellato nel 2007; sembra che il supporto per il &lt;em&gt;Framework .NET&lt;/em&gt; continui in un &lt;a title="Link esterno" href="http://irrlichtnetcp.sourceforge.net/index.php/Main_Page"&gt;progetto parallelo&lt;/a&gt;, ma non ho mai testato o verificato la bontà&amp;#160; di questa iniziativa.&lt;/p&gt;

&lt;p&gt;Dopo un mio disinteressamento di questo progetto dovuto a questione di tempo e conoscenze mie limitate nel 3D, ho voluto riprovare l&amp;#8217;evoluzione di &lt;em&gt;Irrlicht&lt;/em&gt; qualche tempo fa. In contemporanea mi stavo dilettando con il &lt;em&gt;Framework Qt&lt;/em&gt; di cui ho parlato nel blog citato prima. Essendo &lt;em&gt;Irrlicht&lt;/em&gt; multipiattaforma ho provato a unire i due mondi in un piccolo progetto in &lt;em&gt;C++&lt;/em&gt;. Niente di complicato, il tutto si basa su una ambientazione esterna in 3D in cui ci si può muovere liberamente o quasi in cui sono presenti alcune &lt;em&gt;feauture&lt;/em&gt; presenti in &lt;em&gt;Irrlicht&lt;/em&gt;: oggetti 2D, animazioni, terreno, &lt;em&gt;skybox&lt;/em&gt;, gestione delle collisioni e altro. Nel file &lt;em&gt;zip&lt;/em&gt; in cui link è presente alla fine di questo post, è presente la versione già&amp;#160; compilata per &lt;em&gt;Windows&lt;/em&gt; e per &lt;em&gt;Linux&lt;/em&gt;, ma non per &lt;em&gt;Mac&lt;/em&gt; di cui non me ne frega assolutamente nulla. Una volta lanciato in entrambe i sistemi operativi viene visualizzato la prima &lt;em&gt;windows form&lt;/em&gt; con cui si può scegliere se visualizzare il tutto a pieno schermo e il tipo di &lt;em&gt;device&lt;/em&gt; per il &lt;em&gt;rendering&lt;/em&gt; - &lt;em&gt;OpenGL&lt;/em&gt; o due versioni di rendering software, queste ultime due comode in caso ci fossero problemi con il 3D di &lt;em&gt;OpenGL&lt;/em&gt;; non ho inserito la voce &lt;em&gt;directx&lt;/em&gt; perché non sarebbe in alcun modo utilizzabile su altri sistemi operativi non Microsoft.&lt;/p&gt;

&lt;p&gt;Su &lt;em&gt;Linux&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img title="Prima schermata su linux ubuntu" border="0" alt="Prima schermata su linux ubuntu" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_3.png" width="508" height="581" /&gt; &lt;/p&gt;

&lt;p&gt;Su &lt;em&gt;Windows&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img title="Schermata iniziale su Windows" border="0" alt="Schermata iniziale su Windows" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_f8cffc27-b9fd-417d-85ed-b19bd473e6c4.png" width="512" height="588" /&gt; &lt;/p&gt;

&lt;p&gt;Una volta cliccato sul &lt;em&gt;button&lt;/em&gt; &amp;#8216;Avvia Demo&amp;#8217; sarà avviato il &lt;em&gt;device&lt;/em&gt; 3D e caricati tutti gli oggetti:&lt;/p&gt;

&lt;p&gt;&lt;img title="Caricamento degli oggetti per il 3D" border="0" alt="Caricamento degli oggetti per il 3D" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_c6b1b7e1-a7f9-44cb-a216-d5fc09bd2345.png" width="524" height="410" /&gt; &lt;/p&gt;

&lt;p&gt;E quindi si entrerà&amp;#160; nel mondo 3D:&lt;/p&gt;

&lt;p&gt;&lt;img title="Primo mondo 3D" border="0" alt="Primo mondo 3D" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_f2b72656-fe68-4e65-9b2c-67431873bfb7.png" width="524" height="412" /&gt; &lt;/p&gt;

&lt;p&gt;Ho aggiunto anche la visualizzazione di un piccolo help: nella zona di questo cartello è sufficiente premete la barra spaziatrice per avere qualche info. Per iniziare è sufficiente muovere il mouse per &lt;em&gt;guardarci attorno&lt;/em&gt;. Infine con i tasti cursore ci si può muovere. Se si volge lo sguardo in alto è già possibile vedere le animazioni gestite da &lt;em&gt;Irrlicht&lt;/em&gt;: un pianeta ruota su se stesso e quella che dovrebbe essere il suo satellite girargli attorno:&lt;/p&gt;

&lt;p&gt;&lt;img title="Oggetti con animazione" border="0" alt="Oggetti con animazione" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_211d4269-8d51-4b16-8d23-0a60a8e3ee4f.png" width="524" height="412" /&gt; &lt;/p&gt;

&lt;p&gt;L&amp;#8217;ambientazione è molto semplice. Il personaggio si ritrova in uno specie di &lt;em&gt;canale&lt;/em&gt; nel terreno dal quale non può uscire e che lo obbliga ad un percorso prestabilito. Prima di proseguire per l&amp;#8217;unica via disponibile, se ci giriamo alle spalle vediamo un altro oggetti di &lt;em&gt;Irrlicht&lt;/em&gt;: io li chiamo banalmente &lt;em&gt;sprite&lt;/em&gt;. Sono immagini 2D inserite all&amp;#8217;interno dell&amp;#8217;ambientazione 3D. Hanno la caratteristica di mostrare sempre la stessa immagine da qualsiasi lato la si guardi: se si ricordano i giochi 3D degli anni &amp;#8216;90 come &lt;em&gt;Doom&lt;/em&gt;, &lt;em&gt;Duke Nuke&lt;/em&gt;m e altri, i cattivoni da sterminare erano realizzati in questo modo:&lt;/p&gt;

&lt;p&gt;&lt;img title="Sprite in ambientazione 3D" border="0" alt="Sprite in ambientazione 3D" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_8e48da1d-8759-42ac-a5d8-14462dfcb464.png" width="524" height="412" /&gt; &lt;/p&gt;

&lt;p&gt;Se si prosegue per il percorso obbligatorio si giunge in un grande spiazzo a cui al centro è presente una costruzione:&lt;/p&gt;

&lt;p&gt;&lt;img title="Museo virtuale all&amp;#39;interno dell&amp;#39;ambientazione 3D" border="0" alt="Museo virtuale all&amp;#39;interno dell&amp;#39;ambientazione 3D" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_91854c1a-922e-4e32-9f56-bdb69b49845a.png" width="524" height="411" /&gt; &lt;/p&gt;

&lt;p&gt;E&amp;#8217; possibile entrare e vedere le opere girando tra le poche stanze:&lt;/p&gt;

&lt;p&gt;&lt;img title="All&amp;#39;interno del museo virtuale in 3D" border="0" alt="All&amp;#39;interno del museo virtuale in 3D" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_5b4a703f-15ff-476f-9cc6-5276492ea73f.png" width="524" height="407" /&gt; &lt;/p&gt;

&lt;p&gt;Per uscire da tutto una pressione decisa sul tasto &lt;em&gt;ESC&lt;/em&gt; chiude il tutto.&lt;/p&gt;

&lt;p&gt;Ma andando nel tecnico, oggetti all&amp;#8217;interno dell&amp;#8217;ambientazione 3D sono stati realizzati con &lt;a title="Link esterno" href="http://www.delgine.com/"&gt;Deled&lt;/a&gt;, un editor 3D gratuito:&lt;/p&gt;

&lt;p&gt;&lt;img title="Deled e il museo virtuale" border="0" alt="Deled e il museo virtuale" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_b6c6b623-24a3-4901-a556-6997de860623.png" width="524" height="356" /&gt; &lt;/p&gt;

&lt;p&gt;Ho usato vari formati per gli oggetti, dai &lt;em&gt;DMF&lt;/em&gt; agli &lt;em&gt;.x&lt;/em&gt; di &lt;em&gt;directx&lt;/em&gt; e &lt;em&gt;Irrlicht&lt;/em&gt; li ha utilizzati senza particolari problemi. Per il terreno &lt;em&gt;Irrlicht&lt;/em&gt; usa una banale immagine &lt;em&gt;bitmap&lt;/em&gt; in scala di grigi, le quali tonalità&amp;#160; creano il dislivello nel terreno 3D quando sarà&amp;#160; creato. Nello &lt;em&gt;zip&lt;/em&gt; con il progetto è presente l'immagine &lt;em&gt;map.bmp&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img title="Mappa utilizzata per la creazione del terrain in Irrlicht" border="0" alt="Mappa utilizzata per la creazione del terrain in Irrlicht" src="http://blogs.aspitalia.com/img/andrewz/3dmultipiattaformaconqteirrlicht_90ab/image_8195ac9e-398c-4d9d-987c-fcdc13ba902b.png" width="242" height="242" /&gt; &lt;/p&gt;

&lt;p&gt;La parte con il colore più scuro sarà utilizzato per creare il dislivello (quanto lo decidiamo noi da codice). All&amp;#8217;avvio del software il protagonista si trova nella parte inferiore, e risalendo nel percorso si ritrova nel grande spiazzo dove è presente il museo.&lt;/p&gt;

&lt;p&gt;Questo progetto, come detto prima, è stato realizzato in &lt;em&gt;C++&lt;/em&gt; con il &lt;em&gt;framework Qt&lt;/em&gt; e l&amp;#8217;ambiente di sviluppo &lt;em&gt;QtCreator&lt;/em&gt;. Per &lt;em&gt;Irrlicht&lt;/em&gt; ho dovuto scaricare sia la versione per &lt;em&gt;Windows&lt;/em&gt; che per &lt;em&gt;Linux&lt;/em&gt;: in quest&amp;#8217;ultimo caso ho dovuto &lt;a title="Link esterno" href="http://www.irrlicht3d.org/wiki/index.php?n=Main.InstallingIrrlicht#BuildUbuntu"&gt;ricompilare&lt;/a&gt; i sorgenti. &lt;em&gt;QtCreator&lt;/em&gt;, come detto nel blog precedente, compila indifferentemente il codice su tutti i sistemi operativi, ma SOLO se si rimane nell&amp;#8217;utilizzo degli oggetti di questo &lt;em&gt;framework&lt;/em&gt;, nel mio caso per l&amp;#8217;utilizzo di Irrlicht ho dovuto utilizzare dei piccoli accorgimenti. Nel progetto ho creato due directory distinte, una per &lt;em&gt;Windows&lt;/em&gt; e una per &lt;em&gt;Linux&lt;/em&gt; dove ho inserito le &lt;em&gt;.dll&lt;/em&gt;/.&lt;em&gt;so&lt;/em&gt; per questi sistemi operativi. Quindi ho dovuto modificare il file .pro per la compilazione adatta dipendentemente dal SO:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;TARGET = Demo3D 
    &lt;br /&gt;TEMPLATE = app 

    &lt;br /&gt;SOURCES += main.cpp \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; dialog.cpp \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; baseobj3d.cpp \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; scene3d.cpp 

    &lt;br /&gt;HEADERS += dialog.h \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; baseobj3d.h \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; scene3d.h 

    &lt;br /&gt;FORMS += dialog.ui 

    &lt;br /&gt;RESOURCES += Resources.qrc 

    &lt;br /&gt;INCLUDEPATH += ./include 

    &lt;br /&gt;unix:LIBS += -L/usr/X11R6/lib \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -L./libUnix \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -lIrrlicht \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -lGL \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -lXxf86vm \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -lXext \ 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; -lX11 

    &lt;br /&gt;win32:LIBS += ./libWin/libIrrlicht.a 

    &lt;br /&gt;DESTDIR = ./finale&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Aggiungendo &lt;em&gt;unix: &lt;/em&gt;e &lt;em&gt;win32:&lt;/em&gt; è possibile includere determinati file e librerie a seconda se compiliamo con &lt;em&gt;Windows&lt;/em&gt; o con &lt;em&gt;Linux&lt;/em&gt;. Nel mio caso ho specificato quale librerie (&lt;em&gt;LIBS:&lt;/em&gt;) dovevano essere utilizzate. Una piccola nota aggiuntiva per &lt;em&gt;Linux&lt;/em&gt;: è indispensabile avere tutta quando necessario per la compilazione sulla propria macchina.&lt;/p&gt;

&lt;p&gt;Dopo questo configurazione si potrà&amp;#160; compilare sia su Windows che &lt;em&gt;Linux&lt;/em&gt; senza alcuna altra modifica al codice e, se tutto è andato a buon fine, ritrovare i file compilati nella directory &lt;em&gt;finale&lt;/em&gt;. In questa directory ho già&amp;#160; inserito i vari file come le immagini e gli oggetti 3D da caricare. Nel file &lt;em&gt;scene.xml&lt;/em&gt; sono presenti tutti gli oggetti da caricare e come/dove devono essere inseriti nell&amp;#8217;ambientazione 3D.&lt;/p&gt;

&lt;p&gt;Come sempre, è tutto rose e fiori? No, ci mancherebbe! Con i driver video installati sulla mia versione di Ubuntu ho notato dei problemi nel rendering dell&amp;#8217;ambientazione 3D come una più bassa qualità del terreno e altri piccoli problemi; inoltre ho dovuto abbassare le qualità&amp;#160; delle &lt;em&gt;texture&lt;/em&gt; perché creava ancora problemi di &lt;em&gt;rendering&lt;/em&gt;, problema che con &lt;em&gt;Windows&lt;/em&gt; non era presente. Inoltre si noterà&amp;#160; che durante l&amp;#8217;esecuzione di questo software la &lt;em&gt;CPU&lt;/em&gt; o uno dei core della &lt;em&gt;CPU&lt;/em&gt; è sempre e costantemente al 100%. Questo è voluto perché si deve avere sempre la maggior potenza di calcolo per il render in qualsiasi istante. &amp;#8220;Anche quando non si fa nulla?&amp;#8221; - Bella domanda.&lt;/p&gt;

&lt;p&gt;Irrlicht non è l&amp;#8217;unico motore 3D disponibile a tutti liberamente. C&amp;#8217;è un&amp;#8217;ampia scelta tra una decina di motori (pochi multipiattaforma) di cui forse il migliore è &lt;a title="Link esterno" href="http://www.ogre3d.org/"&gt;Ogre&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img title="Ogre esempio" alt="Ogre esempio" src="http://farm3.static.flickr.com/2315/3531679406_59b8558410_o.jpg" width="400" height="300" /&gt;&lt;/p&gt;

&lt;p&gt;Non ho realizzato la demo e il progetto con &lt;em&gt;Ogre&lt;/em&gt; perché per mancanza di tempo non sono mai andato oltre ad uno studio iniziale, e le mie conoscenze passate di &lt;em&gt;Irrlicht&lt;/em&gt; mi hanno velocizzato notevolmente nello sviluppo a tempo perso del progettino qui incluso che voleva essere solo un esempio un po&amp;#8217; più complesso del solito per &lt;em&gt;Qt&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Dimenticavo: il progetto lo si può scaricare da questo &lt;a title="Link esterno" href="http://www.megaupload.com/?d=PXHJKWDU"&gt;link&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Off_Topic/" rel="tag"&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2633/3D-Multipiattaforma-QT-Irrlicht.aspx"&gt;&lt;em&gt;3D multipiattaforma con QT e Irrlicht&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Software, Off Topic</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2633/3D-Multipiattaforma-QT-Irrlicht.aspx</guid><slash:comments>1</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2633/3D-Multipiattaforma-QT-Irrlicht.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2633.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2633</trackback:ping></item><item><title>QtCreator</title><link>http://blogs.aspitalia.com/az/post2617/QtCreator.aspx</link><pubDate>Sun, 02 May 2010 18:10:46 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2617" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;La realtà non è solo Windows. Lo viluppo di un software che sia &lt;em&gt;casereccio&lt;/em&gt; o abbia grande aspettative può scontrarsi anche con questa necessità: poter girare anche su altri sistemi operativi. &lt;em&gt;Java&lt;/em&gt; in primis, ma anche da qualche tempo il &lt;em&gt;Framework .NET&lt;/em&gt; che, grazie a &lt;em&gt;Mono&lt;/em&gt;, può girare anche su &lt;em&gt;Linux&lt;/em&gt; e &lt;em&gt;Mac&lt;/em&gt;, cercano di risolvere questa necessità. Il metodo utilizzato è semplice: dopo la compilazione, creano un eseguibile in &lt;em&gt;bytecode&lt;/em&gt;, un linguaggio intermedio, che una macchina virtuale permette di eseguire. Praticamente possiamo far eseguire qualsiasi programma compilato in &lt;em&gt;bytecode&lt;/em&gt; su qualsiasi sistema operativo che possiede questa macchina virtuale. Il &lt;em&gt;Framework .NET&lt;/em&gt; o &lt;em&gt;Java&lt;/em&gt; mettono a disposizione un gran numero di classi per quasi tutte le esigenze che un programmatore può aver bisogno, in modo che il programmatore non si deve scervellare per cercare accessi diretti a funzioni del &lt;em&gt;kernel&lt;/em&gt;. Questo porterebbe già un grave problema di &lt;em&gt;interoperabilità&lt;/em&gt; visto che, ovviamente, una funzione, per esempio la lettura di un file, è presente in un &lt;em&gt;kernel&lt;/em&gt; in un determinato modulo mentre in un altro sistema operativo può essere in tutt'altro posto o non essere nemmeno disponibile. Nel nostro programma abbiamo la necessità di leggere un file? Bene, in &lt;em&gt;C#&lt;/em&gt; con il &lt;em&gt;Framework .NET&lt;/em&gt; scriviamo:&lt;/p&gt; &lt;p&gt;&lt;em&gt;string content = System.IO.File.RealAllText("nomefile.txt");&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Girando sul sistema operativo Windows, la &lt;em&gt;Virtual machine&lt;/em&gt; tradurrà questa richiesta con il sottoinsieme di funzioni presenti nel Kernel del sistema operativo per leggere il file in questione; lo stesso codice, girando su Linux, non dovrà essere modificato e personalizzato per questo sistema operativo, e ci penserà &lt;em&gt;Mono&lt;/em&gt; a tradurre la richiesta di lettura del file con le corrette richieste al Kernel di Linux. I benefici sono facilmente comprensibili visto che non c'è alcuna perdita di tempo nel convertire nessuna riga nel nostro codice per permettere la corretta esecuzione del nostro software su più sistemi operativi. La semplicità dell'esempio qui sopra non deve però illudere: un software non si basa sempre per chiamate semplici ma spesso anche con procedure proprie della macchina su cui gira. Una &lt;em&gt;windows forms&lt;/em&gt; come quella di cui ho postato un &lt;a title="Mio Blog" href="http://blogs.aspitalia.com/az/post2570/Mono-Framework.-Podi-Semplici-Benchmark-Parte.aspx"&gt;esempio&lt;/a&gt; qualche tempo fa, in ambiente &lt;em&gt;Mono&lt;/em&gt; emula l'aspetto e il funzionamento delle finestre di Windows:&lt;/p&gt; &lt;p&gt;&lt;img alt="test mono 2.4 su ubuntu" src="http://blogs.aspitalia.com/img/andrewz/schermatakarmic32.png"&gt;&lt;/p&gt; &lt;p&gt;Possiamo utilizzare anche librerie presenti per i sistemi operativi di nostro interesse. &lt;a title="Mio blog" href="http://blogs.aspitalia.com/az/post2414/GTK-Giusta-Crocevia-Piattaforme.aspx"&gt;Qui&lt;/a&gt; avevo parlato per esempio delle &lt;em&gt;GTK&lt;/em&gt; che girano perfettamente sia su Windows che su Linux - su Mac non lo so, perché di questa macchina non me ne frega nulla. Già molti software utilizzano questa strada, uno tra tanti &lt;em&gt;Pidgin&lt;/em&gt;, il programma di messaggistica istantanea presente su molti sistemi operativi - anche se qui non si parla di &lt;em&gt;Mono/java&lt;/em&gt;, ma ricompilazione del codice per le macchine interessate. Ed è proprio su questo punto che volevo andare a parare con questo mio post.&lt;/p&gt; &lt;p&gt;Il &lt;em&gt;&lt;a title="Link esterno" href="http://qt.nokia.com/"&gt;Qt toolkit&lt;/a&gt;&lt;/em&gt;, sviluppato dalla &lt;em&gt;QT Software&lt;/em&gt; - prima &lt;em&gt;Trolltech&lt;/em&gt; e in parte sovvenzionata da &lt;em&gt;Nokia&lt;/em&gt; - è un &lt;em&gt;framework&lt;/em&gt; che gira sui principali sistemi operativi: Windows, Mac e Linux (e altri SO per dispotivi mobili). Non è solo una libreria grafica, ma un framework completo che permette la gestione dei file, &lt;em&gt;xml&lt;/em&gt;, &lt;em&gt;tcp&lt;/em&gt;, &lt;em&gt;database&lt;/em&gt;, &lt;em&gt;grafica 2D&lt;/em&gt;, &lt;em&gt;3D&lt;/em&gt; con le &lt;em&gt;OpenGL&lt;/em&gt;, audio e altro. E' utilizzabile con molti linguaggi, dal &lt;em&gt;C++&lt;/em&gt; al &lt;em&gt;Python&lt;/em&gt; e &lt;em&gt;Java&lt;/em&gt;. Da quel che ne so io, era nato un progetto per il loro utilizzo anche on il &lt;em&gt;Framework .NET&lt;/em&gt;, ma da quel che ho letto sembra che tale progetto sia fermo... felice di essere smentito. Forse in ambiente Windows, &lt;em&gt;Qt&lt;/em&gt; non è molto conosciuto, ma basti sapere che in ambiente Linux, insieme alle &lt;em&gt;GTK&lt;/em&gt; su cui su basa il desktop manager &lt;em&gt;Gnome&lt;/em&gt;, è molta conosciuta e utilizzata visto che su di essa si basa il secondo desktop manager più utilizzato, &lt;em&gt;Kde&lt;/em&gt;. In ambiente Windows il software più conosciuto che utilizza questo toolkit è &lt;em&gt;VLC&lt;/em&gt;, il programma per la visione di qualsiasi formato audio e video. Inoltre &lt;em&gt;Nokia&lt;/em&gt; sta puntando molto su questa tecnologia per il suo sistema operativo &lt;em&gt;&lt;a title="Link esterno" href="http://it.wikipedia.org/wiki/Symbian_OS"&gt;Symbian&lt;/a&gt;&lt;/em&gt; per dispositivi mobili, dunque si presenta un probabile futuro roseo visto la posta in gioco di un mondo del portabile in continuo fermento per le numerose notivà (l'argomento meriterebbe una trattazione a sé, ma la voglia non c'è e dunque non ci provo nemmeno).&lt;/p&gt; &lt;p&gt;Oltre al &lt;em&gt;toolkit&lt;/em&gt; è disponibile un ambiente di sviluppo integrato dal nome &lt;em&gt;Qt Creator&lt;/em&gt;. Oltre all'editor di risorse come interfacce grafiche, possiede al suo interno un ambiente di sviluppo basato sul &lt;em&gt;C++&lt;/em&gt;. Scaricabile gratuitamente la versione &lt;a title="Link esterno" href="http://it.wikipedia.org/wiki/GNU_Lesser_General_Public_License"&gt;LGPL&lt;/a&gt; si ha a disposizione un editor completo per le interfacce grafiche e per la scrittura del codice &lt;em&gt;C++&lt;/em&gt; con tanto di &lt;em&gt;intellisense&lt;/em&gt;, come detto, un &lt;em&gt;debugger&lt;/em&gt; e se scaricata la versione &lt;em&gt;SDK&lt;/em&gt;, anche la documentazione completa. Va innanzitutto detto che per la versione per Linux, si deve installare manualmente il compilatore &lt;em&gt;g++&lt;/em&gt;. Nulla di difficile: nel caso di Ubuntu è sufficiente installare il macro pacchetto &lt;em&gt;build-essential&lt;/em&gt; per avere già a disposizione tutto il necessario. Su Windows viene installato di default la versione per questo sistema operativo di &lt;em&gt;mingw&lt;/em&gt;, che non è altro che la versione per questo sistema operativo del compilato &lt;em&gt;c++&lt;/em&gt;, &lt;em&gt;linker&lt;/em&gt; e altri strumenti. Dopo l'installazione saranno presenti anche numerosi esempi ben documentati per le principali funzioni messe a disposizione dal &lt;em&gt;toolkit Qt&lt;/em&gt;. Nelle demo è impressionante trovare anche un browser con tanto di flash funzionante basato sul &lt;em&gt;webkit&lt;/em&gt; - maggiormente compatibile con gli standard di &lt;em&gt;IE&lt;/em&gt;; dunque se avete la necessità di personalizzare il browser secondo le proprio necessità ora si può partire da una base già bella pronta:&lt;/p&gt; &lt;p&gt; &lt;img title="Schermata-1" border="0" alt="Pagina web sul browser in Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/schermata-1_2810b8df-902c-4eb0-8c06-b13c35ba75bc.png" width="520" height="384"&gt; &lt;/p&gt; &lt;p&gt;Gli esempi preposti si possono dividere in due macro categorie: tutorial con codice completo e vere e proprio demo. Nei primo si possono trovare esempi anche semplici, utili per impratichirsi con questo &lt;em&gt;toolkit&lt;/em&gt;, nelle demo troviamo esempi con codice sorgente molto più avanzi, come il browser qui sopra o altri, come il tool grafico seguente che mostra alcune potenzialità grafiche:&lt;/p&gt; &lt;p&gt;&lt;img title="Schermata" border="0" alt="Esempio grafico con Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/schermata_bbfe3ad0-530c-4e0d-afc1-1496dce4e3e8.png" width="520" height="352"&gt; &lt;/p&gt; &lt;p&gt;Ma i vantaggi, come ho cercato di dire precedentemente, non si basano solo sulla potenzialità di questo f&lt;em&gt;ramework&lt;/em&gt;, da dalla compatibilità che possiamo avere, senza il minimo sforzo - o ridotto al minimo, per vedere il nostro codice ricompilato su altre macchine e vedere il tutto funzionare. Tra gli esempi troviamo quello che mostra l'utilizzo delle &lt;em&gt;Multiple document interface&lt;/em&gt; (MDI). Su Linux in Gnome:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="mdi su Linux e Gnome e Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/mdi_3a4460bb-0b13-4484-91dd-6b14d194b0ce.png" width="406" height="428"&gt; &lt;/p&gt; &lt;p&gt;Stesso codice ricompilato su Windows:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="MDI su windows e Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image002_e7ac81e5-36d7-4374-9b03-928c6ecd4d79.jpg" width="408" height="427"&gt; &lt;p&gt;&lt;em&gt;Dialog&lt;/em&gt; con &lt;em&gt;tab&lt;/em&gt; su Linux:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="Dialog con tab su linux e Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image002_ef859e3a-d0ba-4019-b5b5-6966843a297f.png" width="347" height="335"&gt;&lt;/p&gt; &lt;p&gt;Su Windows:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="Dialog con tab su windows e Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image0024.jpg" width="355" height="398"&gt; &lt;p&gt;Un semplice &lt;em&gt;Address book&lt;/em&gt; su Windows:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="Adress book su Windows e Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image0026.jpg" width="418" height="291"&gt; &lt;p&gt;Su Linux: &lt;p&gt;&lt;img border="0" alt="Adress book su linux e Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image0026.png" width="373" height="273"&gt; &lt;p&gt;Tra gli esempi si trova codice utile per qualsiasi scopo: dal &lt;em&gt;2D&lt;/em&gt;, alle utility per uno &lt;em&gt;screenshot&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="Screenshoot scritta in c++ e Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image0028.jpg" width="366" height="384"&gt; &lt;p&gt;Anche esempi per il &lt;em&gt;Drag &amp;amp; drop&lt;/em&gt;, per la gestione dei file, della &lt;em&gt;System tray&lt;/em&gt;, per la visualizzazione di &lt;em&gt;chart&lt;/em&gt;; su Windows: &lt;p&gt;&lt;img border="0" alt="Chart su Windows con Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image00210.jpg" width="642" height="416"&gt; &lt;p&gt;Su Linux: &lt;p&gt;&lt;img border="0" alt="Chart su Linux con Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image0028.png" width="642" height="425"&gt; &lt;p&gt;Ma non solo, anche esempi sull'utilizzo di &lt;em&gt;database&lt;/em&gt;, &lt;em&gt;tcp&lt;/em&gt;, &lt;em&gt;socket&lt;/em&gt;, e molto altro. Si è visto prima l'esempio di un browser completo, anche un &lt;em&gt;client Torrent&lt;/em&gt; è disponibile con tanto di codice e perfettamente funzionante: &lt;p&gt;&lt;img border="0" alt="Selezione del torrent con il client Torrent scritto con Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image00212.jpg" width="481" height="412"&gt; &lt;p&gt;&lt;img border="0" alt="Download con il client Torrent scritto con Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/clip_image00214.jpg" width="539" height="283"&gt; &lt;p&gt;E sempre da questo f&lt;em&gt;ramework&lt;/em&gt;, possiamo gestire/ascoltare anche gli &lt;em&gt;MP3&lt;/em&gt;: &lt;p&gt;&lt;img border="0" alt="MP3 player scritto in C++ e Qt" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/image_142bbed4-7aa6-488f-88d9-d198d696cbfe.png" width="508" height="327"&gt; &lt;p&gt;Per esigenze mie, che non sto a spiegare perché sono fatti miei, ho iniziato a utilizzare le &lt;em&gt;Qt e&lt;/em&gt; dopo i primi problemi con la sintassi del &lt;em&gt;C++&lt;/em&gt; non più utilizzata da anni, mi sono trovato presto a mio agio: spesso mi sono trovato dinanzi a oggetti che ricordano da vicino il &lt;em&gt;Framework .NET&lt;/em&gt; o &lt;em&gt;Java&lt;/em&gt;. Per esempio, per l'utilizzo di stringhe, già facilitata in &lt;em&gt;C++&lt;/em&gt; grazie alle &lt;em&gt;&lt;a title="Link esterno" href="http://it.wikipedia.org/wiki/Standard_Template_Library"&gt;STL&lt;/a&gt;&lt;/em&gt; che ci permette di scrivere: &lt;p&gt;&lt;em&gt;#include &amp;lt;string&amp;gt;&lt;br&gt;using namespace std;&lt;br&gt;...&lt;br&gt;string name="AZ";&lt;/em&gt; &lt;p&gt;Con le &lt;em&gt;Qt&lt;/em&gt; abbiamo a disposizione la classe &lt;em&gt;QString&lt;/em&gt;: &lt;p&gt;&lt;em&gt;#include &amp;lt;QString&amp;gt;&lt;br&gt;...&lt;br&gt;QString name="AZ";&lt;/em&gt; &lt;p&gt;Nella quale troviamo tutte le funzioni di cui un programmatore normalmente ha bisogno: &lt;em&gt;replace&lt;/em&gt;, &lt;em&gt;substring&lt;/em&gt;, &lt;em&gt;find&lt;/em&gt;, &lt;em&gt;startWith&lt;/em&gt;, &lt;em&gt;endWith&lt;/em&gt; e così via. E la vicinanza che &lt;em&gt;&lt;strong&gt;io&lt;/strong&gt;&lt;/em&gt; ho trovato con gli oggetti del &lt;em&gt;Framework .NET&lt;/em&gt;, la si può vedere nella gestione delle liste. Quello che scriviamo in &lt;em&gt;C#&lt;/em&gt;: &lt;p&gt;&lt;em&gt;List&amp;lt;string&amp;gt; coll=new List&amp;lt;string&amp;gt;();&lt;br&gt;coll.Add("AZ");&lt;br&gt;coll.Add("...");&lt;br&gt;string name=coll[0];&lt;/em&gt; &lt;p&gt;Con le &lt;em&gt;Qt&lt;/em&gt; in &lt;em&gt;C++&lt;/em&gt;: &lt;p&gt;&lt;em&gt;QList&amp;lt;QString&amp;gt; coll;&lt;br&gt;coll.append("AZ");&lt;br&gt;coll.append("...");&lt;br&gt;// Oppure:&lt;br&gt;// coll &amp;lt;&amp;lt; "AZ" &amp;lt;&amp;lt; "...";&lt;br&gt;QString name=coll.at(0);&lt;/em&gt; &lt;p&gt;Per le varie conversioni tra oggetti, sono presenti i vari metodi: &lt;p&gt;&lt;em&gt;QString str="12";&lt;br&gt;int num=str.toInt();&lt;/em&gt; &lt;p&gt;Oppure il più generico oggetto &lt;em&gt;QVariant&lt;/em&gt; che ci permette il travaso tra i vari oggetti del &lt;em&gt;Framework Qt&lt;/em&gt;. Altro oggetto molto utilizzato per la gestione delle date è il &lt;em&gt;QDateTime&lt;/em&gt;: &lt;p&gt;&lt;em&gt;QDateTime dt = QDateTime::currentDateTime();&lt;br&gt;QDateTime xmas(QDate(dt.date().year(),12,24), QTime(17,00));&lt;br&gt;int secToXmas = dt.secsTo(xmas);&lt;/em&gt; &lt;p&gt;Se si vuole scrivere un file: &lt;p&gt;&lt;em&gt;#include &amp;lt;QTextStream&amp;gt;&lt;br&gt;#include &amp;lt;QFile&amp;gt;&lt;br&gt;int main()&lt;br&gt;{&lt;br&gt;   QFile data("myfile");&lt;br&gt;   if (data.open(QFile::WriteOnly)) {&lt;br&gt;     QTextStream out(&amp;amp;data);&lt;br&gt;     out &amp;lt;&amp;lt; "Contenuto file di testo" &amp;lt;&amp;lt; endl;&lt;br&gt;   }&lt;br&gt;}&lt;/em&gt; &lt;p&gt;Per leggere: &lt;p&gt;&lt;em&gt;  QFile dataread("myfile");&lt;br&gt;  if (dataread.open(QFile::ReadOnly)) {&lt;br&gt;    QTextStream in(&amp;amp;dataread);&lt;br&gt;    QString content=in.readAll();&lt;br&gt;    dataread.close();&lt;br&gt;}&lt;/em&gt; &lt;p&gt;Per la gestione delle directory c'è &lt;em&gt;QDir&lt;/em&gt;: &lt;p&gt;&lt;em&gt;QString home = QDir::homePath();&lt;/em&gt; &lt;p&gt;Per avere la lista presenti: &lt;p&gt;&lt;em&gt;#include &amp;lt;iostream&amp;gt;&lt;br&gt;#include &amp;lt;QTextStream&amp;gt;&lt;br&gt;#include &amp;lt;QDir&amp;gt;&lt;br&gt;int main(int argc, char *argv[])&lt;br&gt;{&lt;br&gt;    QDir dir;&lt;br&gt;    QStringList filters;&lt;br&gt;    filters &amp;lt;&amp;lt; "*.exe" &amp;lt;&amp;lt; "*.cpp";&lt;br&gt;    dir.setNameFilters(filters); &lt;br&gt;    QFileInfoList list = dir.entryInfoList(); &lt;br&gt;    for (int i = 0; i &amp;lt; list.size(); ++i) {&lt;br&gt;        QFileInfo fileInfo = list.at(i);&lt;br&gt;        std::cout &amp;lt;&amp;lt; QString("%1").arg(fileInfo.fileName()).toStdString();&lt;br&gt;        std::cout &amp;lt;&amp;lt; endl;&lt;br&gt;    }&lt;br&gt;    return 0;&lt;br&gt;}&lt;/em&gt; &lt;p&gt;Ho trovato anche ben fatto la gestione del &lt;em&gt;multi language&lt;/em&gt;: grazie a dei file &lt;em&gt;Xml&lt;/em&gt; si possono definire le &lt;em&gt;label&lt;/em&gt; che da codice possiamo caricare e visualizzare grazie al metodo &lt;em&gt;tr()&lt;/em&gt;: &lt;p&gt;&lt;em&gt;&amp;lt;!DOCTYPE TS&amp;gt;&amp;lt;TS&amp;gt;&lt;br&gt;&amp;lt;context&amp;gt;&lt;br&gt;    &amp;lt;name&amp;gt;FirstPanel&amp;lt;/name&amp;gt;&lt;br&gt;    &amp;lt;message&amp;gt;&lt;br&gt;        &amp;lt;source&amp;gt;Example&amp;lt;/source&amp;gt;&lt;br&gt;        &amp;lt;translation&amp;gt;Esempio&amp;lt;/translation&amp;gt;&lt;br&gt;    &amp;lt;/message&amp;gt;&lt;br&gt;...&lt;br&gt;&amp;lt;/context&amp;gt;&lt;br&gt;&amp;lt;context&amp;gt;&lt;br&gt;    &amp;lt;name&amp;gt;SecondPanel&amp;lt;/name&amp;gt;&lt;br&gt;    &amp;lt;message&amp;gt;&lt;br&gt;        &amp;lt;source&amp;gt;Code&amp;lt;/source&amp;gt;&lt;br&gt;        &amp;lt;translation&amp;gt;Codice&amp;lt;/translation&amp;gt;&lt;br&gt;    &amp;lt;/message&amp;gt;&lt;br&gt;...&lt;br&gt;&amp;lt;/context&amp;gt;&lt;br&gt;&amp;lt;/TS&amp;gt;&lt;/em&gt; &lt;p&gt;Il file &lt;em&gt;xml&lt;/em&gt; può contenere anche più sezioni di codice come si vede sopra. Per poter richiamare il testo: &lt;p&gt;&lt;em&gt;QApplication app(argc, argv);&lt;br&gt;QTranslator translator=translator.load(QString("nomefile"));&lt;br&gt;app.installTranslator(&amp;amp;translator);&lt;br&gt;QString source=tr("Example");&lt;/em&gt; &lt;p&gt;Nella gestione delle interfacce grafiche mi sono immediatamente scontrato con un utilizzo alternativo degli eventi. Le &lt;em&gt;Qt&lt;/em&gt; introducono un nuovo modo per la comunicazione di oggetti: i &lt;em&gt;signals&lt;/em&gt; e gli &lt;em&gt;slots&lt;/em&gt;. Avendo un pulsante nella &lt;em&gt;windows application&lt;/em&gt;, se vogliamo che al &lt;em&gt;click&lt;/em&gt; di un &lt;em&gt;button&lt;/em&gt; sia eseguito il nostro codice, doabbiamo collegare il &lt;em&gt;signal&lt;/em&gt; del &lt;em&gt;click&lt;/em&gt; del &lt;em&gt;button&lt;/em&gt; ad uno &lt;em&gt;slot&lt;/em&gt; presente nel codice (anche se è possibile farlo da interfaccia grafica). Per esempio, avedo un &lt;em&gt;QButton&lt;/em&gt; e una &lt;em&gt;QLabel&lt;/em&gt; (tutti gli oggetti all'interno di questo &lt;em&gt;Framework&lt;/em&gt; iniziano con la lettera &lt;em&gt;&lt;strong&gt;Q&lt;/strong&gt;&lt;/em&gt;) nell'interfaccia grafica: &lt;p&gt;&lt;em&gt;connect(ui-&amp;gt;ButtonAZ, SIGNAL(clicked()), this, SLOT(ChangeTextAZ()));&lt;/em&gt; &lt;p&gt;&lt;em&gt;connect&lt;/em&gt; crea il collegamento al &lt;em&gt;click&lt;/em&gt; sul &lt;em&gt;button&lt;/em&gt; al metodo &lt;em&gt;ChangeTextAZ&lt;/em&gt; presente all'interno della stessa classe (&lt;em&gt;this&lt;/em&gt;) dell'interfaccia grafica. Al &lt;em&gt;click&lt;/em&gt; sul &lt;em&gt;button&lt;/em&gt; sarà richiamata la funzione apposita - per esempio: &lt;p&gt;&lt;em&gt;void MainWindow::ChangeTextAZ()&lt;br&gt;{&lt;br&gt;    QString cc=QDateTime::currentDateTime().toString();&lt;br&gt;    ui-&amp;gt;label-&amp;gt;setText(cc);&lt;br&gt;}&lt;/em&gt; &lt;p&gt;Per scollegare uno slot dal signal:&lt;/p&gt;ui-&amp;gt;ButtonAZ-&amp;gt;disconnect(SIGNAL(clicked()));&lt;br&gt; &lt;p&gt;Sia ben chiaro da subito che il loro utilizzo non si limita agli eventi dei &lt;em&gt;button&lt;/em&gt; nella pagina, ma anche ai singoli oggetti creati da noi. Per esempio, la classe scritta in &lt;em&gt;C++&lt;/em&gt; nel seguente modo: &lt;p&gt;&lt;em&gt;class Person&lt;br&gt;{&lt;br&gt;public:&lt;br&gt;  Person() { Age=0;}&lt;br&gt;  int GetAge() { return Age; }&lt;br&gt;  void setAge(int age) { Age=age;}&lt;br&gt;private:&lt;br&gt; int Age;&lt;br&gt;};&lt;/em&gt; &lt;p&gt;Scritta utilizzando gli oggetti di Qt con il supporto dei &lt;em&gt;signals&lt;/em&gt; e &lt;em&gt;slots&lt;/em&gt;, diverrebbe:&lt;/p&gt;&lt;em&gt;#include &amp;lt;QObject&amp;gt;&lt;br&gt;class Person:public QObject&lt;br&gt;{&lt;br&gt; QObject // macro per l'inclusione degli oggetti per l'utilizzo delle funzionalità aggiuntive di Qt&lt;br&gt;public:&lt;br&gt;  Person() { Age=0;}&lt;br&gt;  int GetAge() { return Age; }&lt;br&gt;signals:&lt;br&gt; void changeAge(int age);&lt;br&gt;public slots:&lt;br&gt;  void setAge(int age)&lt;br&gt;  {&lt;br&gt;   if (Age!=age)&lt;br&gt;   {&lt;br&gt;     Age=age;&lt;br&gt;     emit changeAge(age);&lt;br&gt;   }&lt;br&gt;  }&lt;br&gt;private:&lt;br&gt; int Age;&lt;br&gt;};&lt;/em&gt; &lt;p&gt;Ho aggiunto il &lt;em&gt;signal changeAge&lt;/em&gt; e modificato la funzione &lt;em&gt;setAge&lt;/em&gt; impostandolo come &lt;em&gt;slot&lt;/em&gt;. Questo mi permette di collegare questo oggetto ad eventi che possono essere lanciati da un altro oggetto collegato. Se usiamo il codice seguente: &lt;p&gt;&lt;em&gt;Person a,b;&lt;br&gt;connect(&amp;amp;a, SIGNAL(changeAge(int)), &amp;amp;b, SLOT(setAge(int)));&lt;br&gt;a.setAge(36);&lt;br&gt;int c=b.GetAge(); // i conterrà 36&lt;/em&gt; &lt;p&gt;Creati due oggetti, &lt;em&gt;a&lt;/em&gt; e &lt;em&gt;b&lt;/em&gt;, e collegati, assegnando il valore intero 36, la funzione &lt;em&gt;setAge&lt;/em&gt; controllerà inizialmente che non sia già stato assegnato questo valore (per evitare &lt;em&gt;loop&lt;/em&gt;), altrimenti modificherà la variabile intera &lt;em&gt;Age&lt;/em&gt; e scatenerà l'evento &lt;em&gt;ChangeAge&lt;/em&gt; grazie a &lt;em&gt;emit&lt;/em&gt; che, collegato al &lt;em&gt;setAge&lt;/em&gt; dell'oggetto &lt;em&gt;B&lt;/em&gt;, ne modificherà il valore. &lt;p&gt;Come detto in precedenza, possiamo utilizzare qualsiasi editor per l'utilizzo del framework &lt;em&gt;Qt&lt;/em&gt;, anche &lt;em&gt;Visual Studio&lt;/em&gt; con questo &lt;a title="Link esterno" href="http://qt.nokia.com/downloads/visual-studio-add-in"&gt;add-in&lt;/a&gt;. Se vogliamo un editor che sia &lt;em&gt;cross-platform&lt;/em&gt; possiamo utilizzare anche &lt;em&gt;&lt;a title="Link esterno" href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt;&lt;/em&gt;, oppure l'editor nativo delle &lt;em&gt;Qt&lt;/em&gt;: &lt;a title="Link esterno" href="http://qt.nokia.com/"&gt;QtCreator&lt;/a&gt;. Disponibile per Windows, Mac e Linux, è un ottimo e leggero editor che comprende &lt;em&gt;debug&lt;/em&gt;, &lt;em&gt;help&lt;/em&gt; e &lt;em&gt;intellisense&lt;/em&gt; nella stesura del codice, e comprende un buon editor per la creazione delle interfacce grafiche. Su una macchina con Linux (Ubuntu 9.10) ho potuto utilizzarlo senza particolari problemi con una macchina con soli 512MB; con Windows è utilizzabile con quantitativi di ram minimi; su Mac non l'ho provato perché non me ne importa niente di tali macchine. Se dovessi confrontarlo con altri editor come &lt;em&gt;Visual Studio&lt;/em&gt; (uno dei pochi ambienti di sviluppo che conosco bene), il &lt;em&gt;QtCreator&lt;/em&gt; paga pegno per l'&lt;em&gt;intellisense&lt;/em&gt; non al livello di &lt;em&gt;Visual Studio&lt;/em&gt;: nella visualizzione dei metodi non si ha alcun aiuto del tipo il numero di parametri, &lt;em&gt;overload&lt;/em&gt; ed eventuali tipi restituiti: &lt;p&gt;&lt;img border="0" alt="Intellisense in QtCreator" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/image_813a9968-ae9e-4f02-b8c9-9cee188483b9.png" width="338" height="218"&gt;&lt;/p&gt; &lt;p&gt;L'help è di buon livello, ma spesso si trovano poche righe di descrizione e nessun esempio sull'utilizzo. Il &lt;em&gt;debug&lt;/em&gt; fa il suo lavoro:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="Debugger nel QtCreator" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/image_c472f8b8-be77-4b59-b3b3-f3a77bd887b2.png" width="520" height="454"&gt;&lt;/p&gt; &lt;p&gt;E anche la gestione dei &lt;em&gt;thread&lt;/em&gt; in &lt;em&gt;debug&lt;/em&gt; è buono anche se inferiore all'attuale presende in &lt;em&gt;Visual Studio 2010&lt;/em&gt;. L'editor delle interfacce grafiche è ben fatto e, capite le basi di &lt;em&gt;Qt&lt;/em&gt;, permette la creazione di qualsiasi interfaccia:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="Esempio di interfaccia grafica in QtCreator" src="http://blogs.aspitalia.com/img/andrewz/qtcreator_116be/image_c09ed4f4-6875-40e2-ae07-dd355288e69d.png" width="520" height="470"&gt; &lt;/p&gt; &lt;p&gt;In cantiere è già presente il nuovo editor, la versione 2.0, che introdurrà molte novità, tra le quali il &lt;a title="Link esterno" href="http://doc.qt.nokia.com/4.7-snapshot/qdeclarativeintroduction.html"&gt;QML&lt;/a&gt; (&lt;em&gt;Qt Meta-Object  Language&lt;/em&gt;) che permette la creazione di interfacce grafiche in un meta linguaggio interno molto seplice e le &lt;a title="Link esterno" href="http://doc.qt.nokia.com/4.7-snapshot/qtdeclarative.html"&gt;Qt Declarative Module&lt;/a&gt; e altre novità; per una lista completa si veda questo &lt;a title="link esterno" href="http://doc.qt.nokia.com/4.7-snapshot/qt4-7-intro.html"&gt;link&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Ok, dopo questa breve divagazione, la domanda lecita potrebbe essere: "Ma quanto pesa tutto ciò negli eseguibili?". Su Linux praticamente nulla visto che le Qt sono installabili dai repository e nel caso di Kde sono già installate di default. Su Windows la risposta è il solito e stancante &lt;em&gt;dipende&lt;/em&gt;! Dipende da quanti e quali oggetti del Framework Qt vengono utilizzati. Per una mia windows application ho dovuto includere nella directory dell'eseguibile i seguenti file:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;QtCore4.dll&lt;/em&gt; (2.359 Kb)&lt;/li&gt; &lt;li&gt;&lt;em&gt;QtGui4.dll&lt;/em&gt; (9.293 Kb)&lt;/li&gt; &lt;li&gt;&lt;em&gt;QtXml4.dll&lt;/em&gt; (389 Kb)&lt;/li&gt; &lt;li&gt;&lt;em&gt;libgcc_s_dw2-1.dll&lt;/em&gt; (42 Kb)&lt;/li&gt; &lt;li&gt;&lt;em&gt;mingwm10.dll&lt;/em&gt; (12 Kb)&lt;/li&gt; &lt;li&gt;&lt;em&gt;qjpeg4.dll&lt;/em&gt; (188 kb)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Qui parlo di un piccolo problema che avevo riscontrato all'esecuzione di tale codice su Windows. Inizialmente installato tale software su un'altra macchina con Windows Vista non mi venivano visualizzate le immagini. Solo dopo scopro che è necessario utilizzare la &lt;em&gt;dll qjpeg4&lt;/em&gt;. Secondo la documentazione la inscerisco nella &lt;em&gt;directory&lt;/em&gt; dove c'è l'eseguibile, più precisamente, in &lt;em&gt;plugins\imageformats&lt;/em&gt;, e mi accorgo che le immagini non vengono ancora visualizzate. Solo dopo una ricerca in internet, scopro che è necessario aggiungere il &lt;em&gt;file&lt;/em&gt; di configurazione nella stessa &lt;em&gt;directory&lt;/em&gt; dell'eseguibile, con il nome &lt;em&gt;qt.conf&lt;/em&gt; e con questo contenuto:&lt;/p&gt; &lt;p&gt;&lt;em&gt;[Paths]&lt;br&gt;plugins=./plugins&lt;/em&gt; &lt;p&gt;Questo problema sotto Linux non c'è. Comunque, aggiungendo che l'esegubile era per il mio esempio sotto al mega, il tutto si è risolto in circa 12 MB - l'applicativo d'esempio era una &lt;em&gt;windows forms&lt;/em&gt; con effetti &lt;em&gt;2D&lt;/em&gt; e gestione di foto e dati informativi personali. Per applicazioni che devono diversificare il tipo di compilazione e inclusioni oggetti specifici del sistema in cui gira, è sufficiente mettere mano al file &lt;em&gt;nomeprogetto.pro&lt;/em&gt;:&lt;/p&gt; &lt;p&gt;TARGET = Esempio&lt;br&gt;TEMPLATE = app&lt;br&gt;SOURCES += main.cpp \&lt;br&gt;    objects.cpp&lt;br&gt;HEADERS += objects.h&lt;br&gt;FORMS += dialog.ui&lt;br&gt;RESOURCES += Resources.qrc&lt;br&gt;INCLUDEPATH += ./include&lt;br&gt;unix:LIBS += -L/usr/X11R6/lib \&lt;br&gt;    -LMySharedClass&lt;br&gt;win32:LIBS += ./MySharedClass.a&lt;br&gt;DESTDIR = ./final&lt;/p&gt; &lt;p&gt;Precedendo con &lt;em&gt;win32:&lt;/em&gt; o &lt;em&gt;unix:&lt;/em&gt; possiamo specificare, nell'esempio sopra, quale library includere utilizzare nel caso di Windows (nel primo caso) o di Linux (nel secondo) - è presente anche &lt;em&gt;macx:&lt;/em&gt; per la cronaca... Con questo trucchetto possiamo anche includere anche i nostri file &lt;em&gt;.cpp&lt;/em&gt; da compilare dipendentemente dal sistema operativo su cui sarà compilata l'applicazione:&lt;/p&gt; &lt;p&gt;&lt;em&gt;win32 {&lt;br&gt;     SOURCES += hellowin.cpp&lt;br&gt; }&lt;br&gt; unix {&lt;br&gt;     SOURCES += hellounix.cpp&lt;br&gt; }&lt;/em&gt; &lt;p&gt;Magari in futuro pubblicherò un esempio completo di un'applicazione scritta in &lt;em&gt;Qt&lt;/em&gt; compilabile sia su Windows che Linux senza alcuna modifica che sfrutti librerie esterne. &lt;p&gt;Un'altra domanda lecita potrebbe essere: "Quanto è performante il codice compilato con questo ambiente di sviluppo se confrontato con quello prodotto dai compilatori in &lt;em&gt;Visual Studio&lt;/em&gt;?". Sinceramente non ho mai trovato documentazione a riguardo e i test banali fatti personalmente non mi hanno dato alcuna risposta valida a questo quesito. &lt;p&gt;Un altro pregio che ho trovato nel mondo &lt;em&gt;Qt&lt;/em&gt;, è la ricca documentazione che si può trovare sia sul sito ufficiale che in molte altre &lt;em&gt;community&lt;/em&gt;. Per esempio, cito la internazionale &lt;a title="Link esterno" href="http://www.qtcentre.org/content/"&gt;Qt Centre&lt;/a&gt;. In Italia una &lt;a title="Link esterno" href="http://www.qt-italia.org/"&gt;giovane community&lt;/a&gt; si è affacciata da poco tempo e propone già dei buoni contenuti per la lingua Italiana.&lt;/p&gt; &lt;p&gt;Basta, ho scritto troppo. Si può però capire come questo &lt;em&gt;framework&lt;/em&gt; mi sia piaciuto. Non ho potuto scoprire tutto l'immenso mondo nascosto dietro alle due lettere &lt;em&gt;Qt&lt;/em&gt; causa il poco tempo libero che ho potuto dedicare alla semplice scoperta di questa tecnologia, ma darei un voto molto alto - naturalmente è un parere completamente PERSONALE, dunque di eventuali critiche non me ne frega niente.&lt;/p&gt; &lt;p&gt;Ma dunque è tutto oro quel che luccica? No. Ho riscontrato vari problemini, alcuni dei quali citati prima. Innanzitutto, nella versione per Windows ho notato strane anomalie dell'ambiete di sviluppo &lt;em&gt;QT Creator&lt;/em&gt;. Per esempio, su un portatile con Windows XP ho riscontrato errori nella ricompilazioni dei sorgenti presenti negli esempi, oppure l'help non funzionante - con Linux/Ubuntu invece nessuno di questi problemi. Inoltre con codice &lt;em&gt;C++&lt;/em&gt; scritto non utilizzando gli oggetti di &lt;em&gt;Qt&lt;/em&gt;, ho notato blocchi casuali del &lt;em&gt;debugger&lt;/em&gt; su entrambi i sistemi operativi (ma questo potrebbe essere dovuto a qualche sciocchezza scritta da me: la mia poca esperienza in &lt;em&gt;C++&lt;/em&gt; potrebbe esserne la causa principale).&lt;/p&gt; &lt;p&gt;Inoltre ho notato che il compilatore va in confusione nel caso che ho descritto nell'esempio qui sopra riguardante l'oggetto che si interfaccia con i &lt;em&gt;signals&lt;/em&gt; e &lt;em&gt;slots&lt;/em&gt;. Sempre casualmente, se si scrive un proprio oggetto e si aggiunge in un secondo tempo il supporto e &lt;em&gt;l'inheritance&lt;/em&gt; a &lt;em&gt;QObject&lt;/em&gt;, il compilatore non riesce a riconoscere questo nuovo oggetto ed emette l'errore: "&lt;em&gt;Undefined reference to vtable&lt;/em&gt;". Da quel che ho visto il problema è dovuto dal fatto che &lt;em&gt;QtCreator&lt;/em&gt; aggiunge un file con il &lt;em&gt;moc_nomeclasse.cpp&lt;/em&gt; che viene creato solo se all'aggiunta nell'ambiente di sviluppo di tale classe viene subito definito l'&lt;em&gt;inheritance&lt;/em&gt; con &lt;em&gt;QObject&lt;/em&gt;; l'unica soluzione è cancellare tale classe, con i relativi file, e aggiungerla nuovamente al progetto.&lt;/p&gt; &lt;p&gt;Ora attendo la nuova versione sia di &lt;em&gt;QtCreator&lt;/em&gt; che del Framework stesso dove importanti novità saranno introdotte. Basta mi fermo qui, perché altrimenti mi viene voglia di spalare ***** su altre tecnologie... So che ho solo sfiorato l'argomento &lt;em&gt;Qt&lt;/em&gt;, e che sicuramente ho tralasciato molti altri aspetti importanti. Ma - è un mio punto di vista - la trasportabilità del codice e poterlo riutilizzare su più piattaforme è - e sarà - sempre più importante, senza dover riscrivere ogni volta parte del codice o reimplementare funzioni dello stesso. Il mondo non è solo Windows, e due...&lt;/p&gt; &lt;p&gt;Naturalmente tutto quanto esposto qui, è sotto licenza IMHO! Il mio tempo libero lo utilizzo come mi pare. Oggi in Spagna ha vinto Lorenzo in motogp e tra sette giorni inizia il giro d'Italia finalmente; oggi piove ed ho i tergicristalli della macchina rovinati da parecchio tempo e non ho avuto ancora il tempo di cambiarli.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Object_Oriented_Programming/" rel="tag"&gt;Object Oriented Programming&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/Visual_Studio/" rel="tag"&gt;Visual Studio&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2617/QtCreator.aspx"&gt;&lt;em&gt;QtCreator&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Software, Object Oriented Programming, Visual Studio</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2617/QtCreator.aspx</guid><slash:comments>7</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2617/QtCreator.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2617.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2617</trackback:ping></item><item><title>Office 2010 e i formati aperti</title><link>http://blogs.aspitalia.com/az/post2613/Office-2010-Formati-Aperti.aspx</link><pubDate>Thu, 22 Apr 2010 17:49:52 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2613" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Vediamo se funziona ancora il mio blog. Sempre molto assente sono. Peccato. Oggi è stato un giorno di test. Uscito Office 2010 è stato subito installato e testato anche se lo conoscevo da qualche mese visto che lo seguo dalla versione beta. Ne approfitto oggi per l'installazione sulla macchina di lavoro e mi trovo una richiesta all'avvio che non avevo mai visto nelle versioni in fase di sviluppo:&lt;/p&gt; &lt;p&gt;&lt;img title="office 2010" border="0" alt="office 2010" src="http://blogs.aspitalia.com/img/andrewz/office2010eiformatiaperti_1171d/office2010_3.jpg" width="514" height="381" /&gt; &lt;/p&gt; &lt;p&gt;Troppi processi hanno fatto in modo che venisse chiesto anche in Office quale formato usare di default? Office o OpenOffice/ODF? Ottima cosa.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Off_Topic/" rel="tag"&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2613/Office-2010-Formati-Aperti.aspx"&gt;&lt;em&gt;Office 2010 e i formati aperti&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Software, Off Topic</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2613/Office-2010-Formati-Aperti.aspx</guid><slash:comments>0</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2613/Office-2010-Formati-Aperti.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2613.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2613</trackback:ping></item><item><title>Anno (quasi) nuovo, layout nuovo</title><link>http://blogs.aspitalia.com/az/post2577/Anno-Quasi-Layout.aspx</link><pubDate>Wed, 30 Dec 2009 13:42:37 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2577" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Qualche tempo fa avevo &lt;a title="link esterno" href="http://blogs.aspitalia.com/az/post2560/ot-auguri-10-anni-me.aspx"&gt;festeggiato&lt;/a&gt; i dieci anni. in questi giorni di meritato riposo ne ho approfittato per rifare il layout del &lt;a title="link esterno" href="http://ciclismo.sitiasp.it/"&gt;sito&lt;/a&gt; in questione: dopo otto anni era giunto il momento di qualche cambiamento.&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="nuovo layout sito http://ciclismo.sitiasp.it" src="http://blogs.aspitalia.com/img/andrewz/annoquasinuovolayoutnuovo_cedd/mini_1.jpg" width="500" height="370"&gt; &lt;/p&gt; &lt;p&gt;Ne è valsa la pena? Ma chi lo sa. Auguri 2010!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Off_Topic/" rel="tag"&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2577/Anno-Quasi-Layout.aspx"&gt;&lt;em&gt;Anno (quasi) nuovo, layout nuovo&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Tra i monti, Off Topic</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2577/Anno-Quasi-Layout.aspx</guid><slash:comments>0</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2577/Anno-Quasi-Layout.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2577.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2577</trackback:ping></item><item><title>Mono e Framework... un po&amp;#39; di semplici benchmark parte seconda</title><link>http://blogs.aspitalia.com/az/post2570/Mono-Framework.-Podi-Semplici-Benchmark-Parte.aspx</link><pubDate>Mon, 16 Nov 2009 20:45:00 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2570" border="0" style="width:1px; height:1px;" /&gt;
&lt;p&gt;Poco più di un anno fa avevo scritto un &lt;a title="link esterno" href="http://blogs.aspitalia.com/az/post2419/mono-framework.-podi-semplici-benchmark.aspx"&gt;blog&lt;/a&gt; dove avevo confrontato le prestazioni di una windows forms scritta in .net su una macchina con Windows XP e una macchina Linux con la versione 1.9 di mono. In questi mesi Mono ha raggiunto la versione 2.4 e gode di ottima salute malgrado ci siano i soliti estremisti che solo all'idea di una tecnologia portata dal mondo Microsoft stanno male. Anche se sempre un paio di versioni indietro da ciò che il Framework offre su sistemi operativi Microsoft, siamo ormai giunti anche al supporto di Linq, di cui potrei parlare in un blog futuro sempre se ne avrò voglia. Per questo lunedì sera mi accontenterò di rifare lo stesso test di un anno fa con l'ultima versione di Mono che gira sull'ultima versione di Ubuntu (9.10) e sempre sulla stessa macchina. Ecco il risultato della piccola applicazione la cui descrizione delle operazioni che esegue ho spiegato nel &lt;a title="link esterno" href="http://blogs.aspitalia.com/az/post2419/mono-framework.-podi-semplici-benchmark.aspx"&gt;blog&lt;/a&gt; prima citato:&lt;/p&gt;&lt;p&gt;&lt;img alt="test mono 2.4 su ubuntu" title="test mono 2.4" src="http://blogs.aspitalia.com/img/andrewz/schermatakarmic32.png" /&gt;&lt;/p&gt;Stupito. Per quanto può valere questo banale test nel calcolo degli interi e dei &lt;em&gt;double&lt;/em&gt;le prestazioni sono migliorate nettamente, ma anche a confronto della versione originale del Framework che gira su Windows:&lt;br /&gt;&lt;br /&gt;&lt;table cellspacing="2" cellpadding="0" border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Integer&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Double&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Xml 1&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Xml 2&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Windows .net&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;453,125s&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;1859,375s&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;46,875s&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;4640,625s&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Mono 1.9&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;499,71s&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;2362.398s&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;259,891s&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;26959,493s&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;Mono 2.4&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;286,46s&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;1314,403&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;475,253&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;em&gt;23604,915&lt;/em&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;Grande velocità nella trattazione dei numeri ma nella gestione dei file e xml fa ancora parecchio schifo.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://img.zemanta.com/pixy.gif?x-id=4702ba77-5ad7-825e-8fff-ae73ee648784" /&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/.NET_Framework/" rel="tag"&gt;.NET Framework&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/Mono/" rel="tag"&gt;Mono&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2570/Mono-Framework.-Podi-Semplici-Benchmark-Parte.aspx"&gt;&lt;em&gt;Mono e Framework... un po&amp;#39; di semplici benchmark parte seconda&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Mono, .NET Framework</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2570/Mono-Framework.-Podi-Semplici-Benchmark-Parte.aspx</guid><slash:comments>5</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2570/Mono-Framework.-Podi-Semplici-Benchmark-Parte.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2570.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2570</trackback:ping></item><item><title>SCRIBEFIRE4DSteutfocSCRIBEFIRE</title><link>http://blogs.aspitalia.com/az/post2568/SCRIBEFIRE4DSteutfocSCRIBEFIRE.aspx</link><pubDate>Mon, 16 Nov 2009 01:52:48 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2568" border="0" style="width:1px; height:1px;" /&gt;SCRIBEFIRExsxNtSEySCRIBEFIRE&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Off_Topic/" rel="tag"&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2568/SCRIBEFIRE4DSteutfocSCRIBEFIRE.aspx"&gt;&lt;em&gt;SCRIBEFIRE4DSteutfocSCRIBEFIRE&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Imho, Off Topic</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2568/SCRIBEFIRE4DSteutfocSCRIBEFIRE.aspx</guid><slash:comments>3</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2568/SCRIBEFIRE4DSteutfocSCRIBEFIRE.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2568.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2568</trackback:ping></item><item><title>[OT] GMail pensasse ai suoi bug, non alla meteorologia</title><link>http://blogs.aspitalia.com/az/post2567/OT-GMail-Pensasse-Bug-Meteorologia.aspx</link><pubDate>Tue, 10 Nov 2009 17:21:42 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2567" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Selezionando un tema casuale mi sono ritrovato questa sorpresa collegato alla situazione meteo attuale:&lt;/p&gt; &lt;p&gt;&lt;img title="sole" border="0" alt="sole" src="http://blogs.aspitalia.com/img/andrewz/otgmailpensasseaisuoibugnonallameteorolo_10161/gmail3_3.jpg" width="524" height="427" /&gt; &lt;/p&gt; &lt;p&gt;Di seguito:&lt;/p&gt; &lt;p&gt;&lt;img title="nuvoloso" border="0" alt="nuvoloso" src="http://blogs.aspitalia.com/img/andrewz/otgmailpensasseaisuoibugnonallameteorolo_10161/gmail2_3.jpg" width="524" height="427" /&gt; &lt;/p&gt; &lt;p&gt;E infine:&lt;/p&gt; &lt;p&gt;&lt;img title="pioggia" border="0" alt="pioggia" src="http://blogs.aspitalia.com/img/andrewz/otgmailpensasseaisuoibugnonallameteorolo_10161/gmail1_3.jpg" width="524" height="427" /&gt; &lt;/p&gt; &lt;p&gt;Però non riesco a togliere nei nomi dalla rubrica nella pagina. Ci dovrebbero essere priorità, non solo visive per bimbominkia - IMHO.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Off_Topic/" rel="tag"&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2567/OT-GMail-Pensasse-Bug-Meteorologia.aspx"&gt;&lt;em&gt;[OT] GMail pensasse ai suoi bug, non alla meteorologia&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Imho, Off Topic</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2567/OT-GMail-Pensasse-Bug-Meteorologia.aspx</guid><slash:comments>0</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2567/OT-GMail-Pensasse-Bug-Meteorologia.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2567.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2567</trackback:ping></item><item><title>[OT] Auguri per i 10 anni a me...</title><link>http://blogs.aspitalia.com/az/post2560/OT-Auguri-10-Anni-Me.aspx</link><pubDate>Sat, 31 Oct 2009 10:20:54 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2560" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Era la seconda metà dell'ottobre 1999 quando pubblicai su un &lt;em&gt;hosting free&lt;/em&gt; la prima versione del mio sito del &lt;a title="link esterno" href="http://ciclismo.sitiasp.it/"&gt;ciclismo&lt;/a&gt;. Ricordo che lo feci con &lt;em&gt;Frontpage&lt;/em&gt;. In tutto erano una decina di pagine in HTML. L'idea era nata a me e mio fratello dall'idea di condividere le proprie decennali esperienze ciclistiche per le salite presenti nella mia zona. Ricordo che le prime altimetrie erano realizzate su foglio con righello e matita e poi scannerizzate :)&lt;/p&gt; &lt;p&gt;Nel novembre di quell'anno iniziò la sua conversione in &lt;em&gt;vbscript/asp&lt;/em&gt; che terminò completamente nei primi giorni di dicembre con una nuova interfaccia basata sui frame: titolo e menu a sinistra sempre presenti e parte centrale con il contenuto. Nel 2001 la nuova veste grafica e il passaggio, nella seconda metà dell'anno, in ASP.NET 1.0. I contenuti aumentarono continuamente fino all'implementazione con &lt;a title="link esterno" href="http://www.salite.ch"&gt;Livio&lt;/a&gt; dell'&lt;a title="link esterno" href="http://ciclismo.sitiasp.it/motore.aspx?da=az"&gt;archivio delle salite d'Europa&lt;/a&gt;. Poco dopo il passaggio ad ASP.NET 1.1 e infine alla 2.0. Il database è sempre stato &lt;em&gt;Access&lt;/em&gt;, e per ora ha sempre retto bene anche nei periodi di &lt;em&gt;grande&lt;/em&gt; traffico.&lt;/p&gt; &lt;p&gt;Va be', fine dell'autocelebrazione. So solo che da quel lontano 1999 non avrei mai pensato di festeggiare il decimo anno di quel mio sito completamente amatoriale...&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Off_Topic/" rel="tag"&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2560/OT-Auguri-10-Anni-Me.aspx"&gt;&lt;em&gt;[OT] Auguri per i 10 anni a me...&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Tra i monti, Off Topic</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2560/OT-Auguri-10-Anni-Me.aspx</guid><slash:comments>0</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2560/OT-Auguri-10-Anni-Me.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2560.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2560</trackback:ping></item><item><title>SqLite vs Access vs Sql Ce 3.5</title><link>http://blogs.aspitalia.com/az/post2555/SqLite-Access-Sql-3.5.aspx</link><pubDate>Sat, 24 Oct 2009 19:23:34 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2555" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Per riprendere confidenza alla programmazione dopo un periodo di riposo forzato, ho messo mano in questi giorni al mio &lt;a title="link esterno" href="http://ciclismo.sitiasp.it/"&gt;sito&lt;/a&gt; per ottimizzare il codice e per nuove implementazioni che da troppo tempo erano in cantiere. A parte la primissima versione del sito che era fatta completamente in &lt;em&gt;html&lt;/em&gt; senza nessun supporto &lt;em&gt;server side&lt;/em&gt;, nella sua implementazione prima con il &lt;em&gt;classic asp&lt;/em&gt; e poi con &lt;em&gt;asp.net&lt;/em&gt;, si è sempre basato sul database &lt;em&gt;Access&lt;/em&gt;. Tuttora sono due i database che tengono in piedi il tutto senza grosse fatiche e il minimo uso di cache presente ha permesso che non ci fossero rallentamenti e problemi dovuto ad un uso massiccio di questo tipo di database.&lt;/p&gt; &lt;p&gt;Proprio durante la fase di sviluppo di questi giorni è nata l'idea di prendere in considerazione anche altri database. Innanzitutto, essendo il sito su un &lt;em&gt;hosting povero&lt;/em&gt;, non ho a disposizione database degni di questo nome come &lt;em&gt;Sql Server&lt;/em&gt; o &lt;em&gt;MySql&lt;/em&gt;, e arrangiarsi alla bell'e meglio è ciò che mi ha obbligato a guardarmi attorno alla ricerca di alternative e, perché no, mi ha permesso di prendere confidenza con qualcosa di nuovo. Pensandoci bene, a parte la mia esigenza personale dettata dal mio sito e viste le alternative possibili, è proprio obbligatorio passare ad &lt;em&gt;hosting&lt;/em&gt; più costosi per siti con basso traffico solo per avere un database serio quando il numero di richieste pagine/query è talmente basso da far apparire addirittura sprecato un &lt;em&gt;hosting&lt;/em&gt; con &lt;em&gt;Sql Server&lt;/em&gt; o &lt;em&gt;MySql&lt;/em&gt;? In fondo, se uno prende uno spazio di &lt;em&gt;hosting&lt;/em&gt; per inserire un proprio blog o come contenitore di informazioni personali, dunque con una previsione almeno iniziale di carico molto basso, anche &lt;em&gt;Access&lt;/em&gt; può far degnamente il suo lavoro. Ma perché non prendere in considerazione anche altre alternative?&lt;/p&gt; &lt;p&gt;In questo blog voglio solo trascrivere le mie sensazione nell'uso e di test personali nell'uso di tre database utilizzabili nelle proprie medio piccole web application:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Access &lt;li&gt;SqLite &lt;li&gt;Sql CE&lt;/li&gt;&lt;/ul&gt; &lt;h1&gt;&lt;/h1&gt; &lt;p&gt;&lt;em&gt;Access&lt;/em&gt; per i più non ha bisogno di presentazione. Prima o poi lo incontrano tutti nel loro percorso informatico. Probabilmente il più facile database disponibile ed è facilmente utilizzare fin dai tempi del &lt;em&gt;classic asp&lt;/em&gt;: è sufficiente prendere il file del database (.&lt;em&gt;mdb&lt;/em&gt;) e copiarlo in una directory sul server, e senza alcun'altra installazione sul server, si può interrogare da codice con poche righe di codice. I suoi difetti maggiori sono le prestazioni e l'impossibilità di usarlo in multiutenza. Per le web application il problema maggiore rimane solo il primo visto che se in lettura molte pagine possono accedere contemporaneamente, in scrittura solo un'operazione alla volta è possibile.&lt;/p&gt; &lt;p&gt;La connessione, avviene grazie ai driver &lt;em&gt;ole-db&lt;/em&gt;, e il Framework mette a disosizione un namespace apposito: &lt;em&gt;System.Data.OleDb&lt;/em&gt;, con tutta la sua sequenza di classi:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;OleDbConnection &lt;li&gt;OleDbCommand &lt;li&gt;OleDbDataAdapter &lt;li&gt;OleDbDataReader &lt;li&gt;...&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;E utilizzare questa stringa di connessione: "&lt;em&gt;Provider=Microsoft.Jet.OLEDB.4.0;Data source=database.mdb&lt;/em&gt;":&lt;/p&gt; &lt;p&gt;&lt;em&gt;OleDbConnection conn=new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data source=database.mdb");&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;SqLite&lt;/em&gt; è un progetto completamente free e può essere utilizzato per qualsiasi tipo di applicazione. Per utilizzarlo nelle proprio web application in asp.net, è sufficiente copiare il file &lt;em&gt;System.Data.SQLite.dll&lt;/em&gt; nella directory &lt;em&gt;bin&lt;/em&gt; (o creando una &lt;em&gt;refernce&lt;/em&gt; da Visual Studio). Come &lt;em&gt;Access&lt;/em&gt;, anche questo database di basa su un file che ha come suffisso ".s3db". Per creare questo database sono presenti numerosi progetti free, io ho utilizzato il famoso &lt;a title="link esterno" href="http://sqliteadmin.orbmu2k.de/"&gt;SqLite Administrator&lt;/a&gt;:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="image" src="http://blogs.aspitalia.com/img/andrewz/3d8548fc430d_f448/image_7.png" width="524" height="383"&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;SqLite&lt;/em&gt; per il framework è possibile scaricarlo da questo &lt;a title="link esterno" href="http://sourceforge.net/projects/sqlite-dotnet2/"&gt;link&lt;/a&gt;. Una volta installato è possibile trovare i file di nostro interesse nella directory:&lt;/p&gt; &lt;p&gt;&lt;em&gt;C:\Programmi\SQLite.NET\bin&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Oltre alle dll possiamo trovare anche un test di esempio per l'utilizzo di questo database e la documentazione. Inoltre possiamo integrare il &lt;em&gt;designer&lt;/em&gt; di &lt;em&gt;SqLite&lt;/em&gt; direttamente in Visual Studio e con &lt;em&gt;Linq&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;SqLite è utilizzabile dai progetti scritti con il Framework dal namespace &lt;em&gt;System.Data.SQLite&lt;/em&gt; che mette a dispozione le classi apposite:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;SqLiteConnection &lt;li&gt;SqLiteCommand &lt;li&gt;SqLiteDataAdapter &lt;li&gt;SqLiteDataReader &lt;li&gt;...&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;La stringa di connessione è "&lt;em&gt;Data Source=database.s3db&lt;/em&gt;". Per esempio:&lt;/p&gt; &lt;p&gt;&lt;em&gt;SqLiteConnection conn=new SqLiteConnection("Data Source="+Request.MapPath("database.s3db"));&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Anche se non rientra nei canoni dell'obbiettivo di questo blog ho preso in considerazione anche &lt;em&gt;Sql CE&lt;/em&gt; di Microsoft. Se si utilizza per lo sviluppo Visual Studio, probabilmente lo si ritroverà all'interno della propria macchina. Altrimenti è possibile scaricarlo gratuitamente da questo &lt;a title="link esterno" href="http://www.microsoft.com/sqlserver/2005/en/us/compact-downloads.aspx"&gt;link&lt;/a&gt;. La creazione e la gestione delle tabelle è molto semplice visto che è possibile manipolare i file di database di Sql CE (con suffisso ".&lt;em&gt;sdf&lt;/em&gt;") con gli editor di &lt;em&gt;Sql Server&lt;/em&gt;, o con il gratuito Microsoft &lt;a title="link esterno" href="http://www.microsoft.com/downloads/details.aspx?familyid=c243a5ae-4bd1-4e3d-94b8-5a0f62bf7796&amp;amp;displaylang=en"&gt;SQL Server Management Studio Express&lt;/a&gt;. Qui sotto la banale operazione di creazione di un database di questo tipo con il &lt;em&gt;Sql Server Managment Studio&lt;/em&gt; della versione 2008:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="creazione sqlce" src="http://blogs.aspitalia.com/img/andrewz/3d8548fc430d_f448/image_8.png" width="420" height="312"&gt;&lt;/p&gt;  &lt;p&gt;&lt;img border="0" alt="creazione" src="http://blogs.aspitalia.com/img/andrewz/3d8548fc430d_f448/image_9.png" width="443" height="308"&gt;&lt;/p&gt; &lt;p&gt;Come scritto sopra, non rientra nei canoni della mia valutazione perché per inserire questo tipo di database su un server in &lt;em&gt;hosting&lt;/em&gt; per la propria web application, non è sufficiente copiare le &lt;em&gt;dll&lt;/em&gt; ma deve essere installato direttamente sulla macchina. A queste conclusioni sono giunto dopo numerosi tentativi andati a vuoto e dopo una veloce ricerca in rete di una soluzione. Se qualcuno sa una strada che può portare alla soluzione è benvenuta qualsiasi informazioni in merito.&lt;/p&gt; &lt;p&gt;Inserita la &lt;em&gt;reference&lt;/em&gt; a "&lt;em&gt;System.Data.SqlServerCe&lt;/em&gt;" nella web application abbiamo il namespace apposito e le classi per la manipolazione di questo database:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;SqlCeConnection &lt;li&gt;SqlCeCommand &lt;li&gt;SqlCeDataAdapter &lt;li&gt;SqlCeDataReader &lt;li&gt;...&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;La stringa di connessione è uguale a quella che per &lt;em&gt;SqLite&lt;/em&gt;: "&lt;em&gt;Data Source=database.sdf&lt;/em&gt;". Per esempio:&lt;/p&gt; &lt;p&gt;&lt;em&gt;SqlCeConnection conn=new SqlCeConnection("Data Source="+Request.MapPath("database.sdf"));&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Se si prova ad utilizzare &lt;em&gt;Sql CE&lt;/em&gt; in una web application si ha inizialmente una sorpresa trovandosi di fronte all'errore:&lt;/p&gt; &lt;p&gt;&lt;em&gt;"SQL Server Compact Edition is not intended for ASP.NET development"&lt;/em&gt;&lt;/p&gt; &lt;p&gt;La &lt;a title="link esterno" href="http://vidmar.net/weblog/archive/2007/04/19/sql-server-2005-compact-edition-and-asp.net.aspx"&gt;soluzione&lt;/a&gt; si basa nell'aggiunta di questo riga di codice:&lt;/p&gt; &lt;p&gt;&lt;em&gt;AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true);&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Per i miei test ho utilizzato due semplici tabelle con una &lt;em&gt;relation&lt;/em&gt;, aventi questa struttura:&lt;/p&gt; &lt;p&gt;&lt;img border="0" alt="access struttura" src="http://blogs.aspitalia.com/img/andrewz/3d8548fc430d_f448/image_10.png" width="524" height="338"&gt; &lt;/p&gt; &lt;p&gt;&lt;em&gt;FirstName&lt;/em&gt; e &lt;em&gt;Information&lt;/em&gt; sono campi &lt;em&gt;varchar&lt;/em&gt;, &lt;em&gt;Age&lt;/em&gt; è un campo numerico così come &lt;em&gt;ParentId&lt;/em&gt; che lega i record della tabella "&lt;em&gt;Table2&lt;/em&gt;" ai record presenti in "&lt;em&gt;Table1&lt;/em&gt;". Il test si basa sulla scrittura di centiana di record alla volta e a delle query di lettura su questi record in modo ripetuto.&lt;/p&gt; &lt;p&gt;Il primo test si basa sulla scrittura di dieci record nella prima tabella e di trenta nella seconda. Oltre la scrittura, dopo l'inserimento della prima tabella, viene letto l'Id generato dalla tabella per creare il giusto riferimento nella tabella figlia. Qui sotto riporto i tre database:&lt;/p&gt; &lt;table border="1" cellspacing="0" cellpadding="2" width="399"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td  width="76"&gt;&lt;strong&gt;N. tentativi&lt;/strong&gt;&lt;/td&gt; &lt;td  width="86"&gt;&lt;strong&gt;Access&lt;/strong&gt;&lt;/td&gt; &lt;td  width="72"&gt;&lt;strong&gt;SqLite&lt;/strong&gt;&lt;/td&gt; &lt;td  width="85"&gt;&lt;strong&gt;SqLite - T&lt;/strong&gt;&lt;/td&gt; &lt;td  width="78"&gt;&lt;strong&gt;Sql CE 3.5&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="76"&gt;&lt;strong&gt;1°&lt;/strong&gt;&lt;/td&gt; &lt;td  width="86"&gt;&lt;em&gt;0s 93&lt;/em&gt;&lt;/td&gt; &lt;td  width="72"&gt;&lt;em&gt;8s 53&lt;/em&gt;&lt;/td&gt; &lt;td  width="85"&gt;&lt;em&gt;0s 40&lt;/em&gt;&lt;/td&gt; &lt;td  width="78"&gt;&lt;em&gt;0s 73&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="76"&gt;&lt;strong&gt;2°&lt;/strong&gt;&lt;/td&gt; &lt;td  width="86"&gt;&lt;em&gt;0s 98&lt;/em&gt;&lt;/td&gt; &lt;td  width="72"&gt;&lt;em&gt;8s 25&lt;/em&gt;&lt;/td&gt; &lt;td  width="85"&gt;&lt;em&gt;0s 47&lt;/em&gt;&lt;/td&gt; &lt;td  width="78"&gt;&lt;em&gt;0s 74&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="76"&gt;&lt;strong&gt;3°&lt;/strong&gt;&lt;/td&gt; &lt;td  width="89"&gt;&lt;em&gt;0s 93&lt;/em&gt;&lt;/td&gt; &lt;td  width="78"&gt;&lt;em&gt;8s 70&lt;/em&gt;&lt;/td&gt; &lt;td  width="92"&gt;&lt;em&gt;0s 46&lt;/em&gt;&lt;/td&gt; &lt;td  width="89"&gt;&lt;em&gt;0s 71&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Ho dovuto inserire in due colonne i tempi di &lt;em&gt;SqLite&lt;/em&gt; a causa delle prestazioni scadenti di questo database se non utilizziamo procedure apposite per questo tipo di operazione. Il codice di test per l'inserimento di tutti i database si basa su un banale ciclo &lt;em&gt;for&lt;/em&gt;. All'interno di esso eseguo l'apertura della connessione del database, quindi una a una le singole operazioni di scrittura. Pressappoco questo schema:&lt;/p&gt; &lt;p&gt;&lt;em&gt;for (int i=0;i&amp;lt;10;i++)&lt;br&gt;{&lt;br&gt;  // Apri connessione&lt;br&gt;  // Esegue inserimento in tabella 1&lt;br&gt;  // Legge l'ID inserito dal database per l'inserimento&lt;br&gt;  for (int x=0;x&amp;lt;30;x++)&lt;br&gt;  {&lt;br&gt;    // Inserisce record nella tabella 2&lt;br&gt;  }&lt;br&gt;  // Chiude connessione&lt;br&gt;}&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Grazie a questo codice ci si scontra ad un grosso limite di &lt;em&gt;SqLite&lt;/em&gt; che, nelle operazioni di grande inserimento, si scontra con un crollo di prestazioni notevole. Per evitare questo &lt;a title="link esterno" href="http://www.sqlite.org/cvstrac/wiki?p=performanceconsiderations"&gt;problema&lt;/a&gt;, è sufficiente mettere le varie fasi di inserimento in &lt;em&gt;transaction&lt;/em&gt; per avere quel balzo di prestazioni che lo porta al primo posto nella tabella precedente (colonna "&lt;em&gt;SqLite - T&lt;/em&gt;"). Il codice qui sopra va riscritto in questo modo:&lt;/p&gt;&lt;em&gt;for (int i=0;i&amp;lt;10;i++)&lt;br&gt;{&lt;br&gt;  // Apri connessione&lt;br&gt;  // Apri transaction (invio comando "begin")&lt;br&gt;  // Esegue inserimento in tabella 1&lt;br&gt;  // Legge l'ID inserito dal database per l'inserimento&lt;br&gt;  for (int x=0;x&amp;lt;30;x++)&lt;br&gt;  {&lt;br&gt;    // Inserisce record nella tabella 2&lt;br&gt;  }&lt;br&gt;  // Chiususa transaction (invio comando "commit")&lt;br&gt;  // Chiude connessione&lt;br&gt;}&lt;/em&gt; &lt;p&gt;Anche se i distacchi sono limitati, &lt;em&gt;Access&lt;/em&gt; risulta il più lento e &lt;em&gt;SqLite&lt;/em&gt; il più veloce anche se, abbiamo dovuto ottimizzare il codice appositamente per lui. Di seguito ho eseguito delle operazioni ripetute in lettura. Le tabelle, composte da trenta record la prima e novecento la seconda, vengono lette la prima per &lt;em&gt;n&lt;/em&gt; volte, e la seconda viene conteggiata in una query il numero di record. I risultati sono i seguenti:&lt;/p&gt; &lt;table border="1" cellspacing="0" cellpadding="2" width="400"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td  width="100"&gt;&lt;strong&gt;N. tentativi&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;strong&gt;Access&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;strong&gt;SqLite&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;strong&gt;Sql CE 3.5&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="100"&gt;&lt;strong&gt;1°&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;2s 49&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;0s 31&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;1s 33&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="100"&gt;&lt;strong&gt;2°&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;2s 34&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;0s 23&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;1s 25&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="100"&gt;&lt;strong&gt;3°&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;2s 35&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;0s 23&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;1s 26&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Qui non c'è storia: &lt;em&gt;SqLite&lt;/em&gt; fa la differenza. &lt;em&gt;Access&lt;/em&gt; è l'ultimo con distacchi abissali. L'ultimo test di lettura esegue ripetute &lt;em&gt;query&lt;/em&gt; con &lt;em&gt;join&lt;/em&gt; tra le due tabelle.&lt;/p&gt; &lt;table border="1" cellspacing="0" cellpadding="2" width="402"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td  width="100"&gt;&lt;strong&gt;N. tentativi&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;strong&gt;Access&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;strong&gt;SqLite&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;strong&gt;Sql CE 3.5&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="100"&gt;&lt;strong&gt;1°&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;3s 88&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;0s 96&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;2s 55&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="100"&gt;&lt;strong&gt;2°&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;3s 99&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;0s 97&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;2s 55&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  width="100"&gt;&lt;strong&gt;3°&lt;/strong&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;3s 91&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;0s 96&lt;/em&gt;&lt;/td&gt; &lt;td  width="100"&gt;&lt;em&gt;2s 67&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Si possono tirare delle conclusioni? No. Anche se l'informatica si avvicina moltissimo alla matematica è soggetta alla regola che vige in politica e sport dove chiunque può dire il contrario di tutto solo per partito preso. E siccome a me non me ne frega nulla e so che là fuori c'è sempre qualcuno che si sente il diritto di criticare, ognuno tiri le conclusioni per sé. Anzi, consiglio di fare delle prove e valutare. Le banderuole si muovono a seconda di dove tira il vento, e non hanno cervello. Altri lo hanno, &lt;em&gt;deturpato&lt;/em&gt; o meno, ma è più comodo sventolare per simpatie personali.&lt;/p&gt; &lt;p&gt;E siccome non me ne frega nulla - questa frase non varrebbe nulla se non dessi un mio parere personale, perché se non lo facessi vorrebbe dire che mi importerebbe - ecco un mio giudizio: &lt;em&gt;SqLite&lt;/em&gt; è leggero ed ha ottime prestazioni, lo prenderei in considerazione per piccole web application tenendo sempre d'occhio le varie ottimizzazioni per evitare inconvenienti come quello della scrittura che ho citato. &lt;em&gt;Access&lt;/em&gt; si può definire finito nelle web application? Nì: le alternative ci sono e se si vuole dirla tutta, se proprio si vuole un database degno di tal nome perché si prevedono necessità &lt;em&gt;pesanti&lt;/em&gt;, senza dover andare su &lt;em&gt;Sql Server&lt;/em&gt;, ormai tutti i servizi di &lt;em&gt;hosting&lt;/em&gt; anche economico danno &lt;em&gt;MySql&lt;/em&gt; con un piccolo sovrapprezzo. L'&lt;strong&gt;importante&lt;/strong&gt; è sapere che sino alternative. In ogni caso rimando per approfondimenti sui vari database che ho trattato alla numerosa documentazione che è reperibile in Internet - se con questo mio blog ho acceso un po' la curiosità.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/.NET_Framework/" rel="tag"&gt;.NET Framework&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/ADO.NET/" rel="tag"&gt;ADO.NET&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/ASP.NET/" rel="tag"&gt;ASP.NET&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/Database/" rel="tag"&gt;Database&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/SQL_Server/" rel="tag"&gt;SQL Server&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2555/SqLite-Access-Sql-3.5.aspx"&gt;&lt;em&gt;SqLite vs Access vs Sql Ce 3.5&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Sql, .NET Framework, ADO.NET, ASP.NET, Database, SQL Server</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2555/SqLite-Access-Sql-3.5.aspx</guid><slash:comments>3</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2555/SqLite-Access-Sql-3.5.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2555.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2555</trackback:ping></item><item><title>Una alternativa a SkyDrive con un po&amp;#39; di sicurezza</title><link>http://blogs.aspitalia.com/az/post2528/Alternativa-SkyDrive-Podi-Sicurezza.aspx</link><pubDate>Sun, 26 Jul 2009 10:58:00 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2528" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Dopo aver utilizzato per qualche tempo &lt;a href="http://skydrive.live.com/" title="Link esterno"&gt;SkyDrive&lt;/a&gt;, ho deciso di cercare un'alternativa; decisione non dettata da problemi riscontrati da questo servizio, ma per semplice curiosità personale. La casualità di una ricerca in &lt;em&gt;google &lt;/em&gt;mi ha portato a testare &lt;a href="http://www.getdropbox.com/" title="Link esterno"&gt;DropBox&lt;/a&gt;. Innanzitutto propone tre soluzioni, di cui solo la prima gratis, in cui offre 2GB di spazio contro i 25GB di &lt;em&gt;SkyDrive&lt;/em&gt;. Questo limite di &lt;em&gt;DropBox &lt;/em&gt;non mi ha creato problemi visto che non ho necessità di così grande spazio, e nel mio caso i 2GB sono più che sufficienti.&lt;/p&gt;&lt;p align="baseline"&gt;Iscrizione rapida, installato il software, e tutto fuziona senza problemi. Viene creata una &lt;em&gt;directory &lt;/em&gt;in &lt;em&gt;Documenti &lt;/em&gt;che si sincronizzerà con lo spazio remoto. Un dettaglio piacevole è stato quello di scoprire che funziona su &lt;em&gt;Windows&lt;/em&gt;, &lt;em&gt;Mac &lt;/em&gt;(di cui non me ne importa una cippa) e &lt;em&gt;Linux&lt;/em&gt;. Io ho provato solo la versione di Windows e Linux, e su entrambi i sistemi operativi il tutto ha funzionato al primo colpo senza problemi. Il software, una volta installato, inserisce un'icona vicino all'orologio (su entrambi i sistemi operativi, su &lt;em&gt;Linux &lt;/em&gt;ho provato solo con &lt;em&gt;Gnome &lt;/em&gt;e appare nella &lt;em&gt;taskbar &lt;/em&gt;superiore) dove si possono trovare le varie opzioni:&lt;/p&gt;&lt;p&gt;&lt;img src="http://blogs.aspitalia.com/img/andrewz/Immagini/Schermata3.png" /&gt;&lt;/p&gt;&lt;p align="baseline"&gt;La sincronizzazione dei file con il disco virtuale remoto, avvenendo via internet, potrebbe comportare rallentamenti nella connessione, ma tra le opzioni possiamo impostare i vari limiti:&lt;/p&gt;&lt;p&gt;&lt;img src="http://blogs.aspitalia.com/img/andrewz/Immagini/Schermata2.png" /&gt;&lt;/p&gt;&lt;p align="baseline"&gt;Io ho sempre lasciato l'opzione &lt;em&gt;Automatic&lt;/em&gt;, non ho mai riscontrato problemi di velocità.Una volta modificati, inseriti o cancellati i file, è possibile vedere nell'icona animata del programma quello che sta accadendo dietro le quinte nelle varie operazioni di aggiornamento del disco virtuale remoto: anche sui singoli file nella directory interessata è presente una piccola immagine che fa capire immediatamente lo stato di aggiornamento di un file:&lt;/p&gt;&lt;p&gt;&lt;img src="http://blogs.aspitalia.com/img/andrewz/Immagini/Schermata.png" /&gt;&lt;/p&gt;&lt;p&gt;Non sono mai stato una persona che ha dato molta importanza alla riservatezza: in fondo scaricare su un server remoto dei propri file e come dare al gestore, chiunque esso sia, &lt;em&gt;Microsoft &lt;/em&gt;e una qualsiasi azienda sconosciuta, la possibilità di poter guardare e controllarne il contenuto. Ovviamente le cose cambiano quando si tratta di file di lavoro o altri in cui vogliamo manterene la massima riservatezza. Una possibile soluzione che utilizzo che permette quel minimo di sicurezza è grazie a &lt;a href="http://www.truecrypt.org/" title="Link esterno"&gt;TrueCrypt&lt;/a&gt;. E' possibile creare una directory crittografata come file e inserendolo sullo spazio remoto, utilizzarlo come un disco virtuale, sicuri che nessuno possa leggerne il contenuto.&lt;/p&gt;&lt;p&gt;Per i miei scopi ho creato un disco virtuale di 250MB, e dopo un lento upload di circa due ore, ho provato a utilizzarlo con &lt;em&gt;TrueCrypt &lt;/em&gt;per controllarne le prestazioni. Una volta modificato il contenuto di questo disco virtuale, una volta chiuso &lt;em&gt;TrueCrypt&lt;/em&gt;, mi aspettavo l'upload di tutto il file sul server remoto con un'attesa ancora lunghissima per l'invio di tutti i 250MB, ma &lt;em&gt;DropBox &lt;/em&gt;si è comportato in maniera egregia, inviato solo le modifiche del file in pochi secondi.&lt;/p&gt;&lt;p&gt;Ho testato le varie sincronizzazioni tra i vari sistemi operativi, e tutto per ora non mi ha mai dato problemi. Per ora ottimo servizio. Spero di non ricredermi.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Off_Topic/" rel="tag"&gt;Off Topic&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2528/Alternativa-SkyDrive-Podi-Sicurezza.aspx"&gt;&lt;em&gt;Una alternativa a SkyDrive con un po&amp;#39; di sicurezza&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Software, Off Topic</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2528/Alternativa-SkyDrive-Podi-Sicurezza.aspx</guid><slash:comments>0</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2528/Alternativa-SkyDrive-Podi-Sicurezza.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2528.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2528</trackback:ping></item><item><title>Cross apply con i campi XML</title><link>http://blogs.aspitalia.com/az/post2523/Cross-Apply-Campi-XML.aspx</link><pubDate>Sun, 12 Jul 2009 09:50:00 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2523" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Il problema che mi si è posto: tabella con un campo xml contenente dei feed. Un esempio vale più di mille parole:&lt;/p&gt;&lt;pre&gt;SELECT [Id],[Name],[Information] FROM [Test].[dbo].[XmlTest]&lt;br /&gt;&lt;br /&gt;1 AZ1 &amp;lt;root&amp;gt;&amp;lt;feed&amp;gt;Article1&amp;lt;/feed&amp;gt;&amp;lt;feed&amp;gt;Article2&amp;lt;/feed&amp;gt;&amp;lt;feed&amp;gt;Article3&amp;lt;/feed&amp;gt;&amp;lt;/root&amp;gt;&lt;br /&gt;2 AZ2 &amp;lt;root&amp;gt;&amp;lt;feed&amp;gt;Article4&amp;lt;/feed&amp;gt;&amp;lt;feed&amp;gt;Article5&amp;lt;/feed&amp;gt;&amp;lt;/root&amp;gt;&lt;br /&gt;3 AZ3 &amp;lt;root&amp;gt;&amp;lt;feed&amp;gt;Article6&amp;lt;/feed&amp;gt;&amp;lt;feed&amp;gt;Article7&amp;lt;/feed&amp;gt;&amp;lt;feed&amp;gt;Article8&amp;lt;/feed&amp;gt;&amp;lt;/root&amp;gt;&lt;/pre&gt;&lt;p&gt;Problema: con un query è possibile avere la lista dei feed contemporaneamente con un'unica query senza dover utilizzare &lt;em&gt;Linq&lt;/em&gt;, &lt;em&gt;anonymous type&lt;/em&gt; o &lt;em&gt;miciomiciobaubau&lt;/em&gt;?&lt;/p&gt;&lt;p&gt;Sì, con questa query che utilizza il &lt;em&gt;cross apply&lt;/em&gt;:&lt;/p&gt;&lt;code&gt;select [Id],[Name],s.x.query( '.' )&lt;br /&gt;from [Test].[dbo].[XmlTest]&lt;br /&gt;cross apply [Information].nodes('/root/feed') s( x )&lt;/code&gt;&lt;p&gt;Che ci permette di avere:&lt;/p&gt;&lt;code&gt;1 AZ1&amp;#xa0; &lt;feed&gt;Article1&lt;/feed&gt;&lt;br /&gt;1 AZ1&amp;#xa0; &lt;feed&gt;Article2&lt;/feed&gt;&lt;br /&gt;1 AZ1&amp;#xa0; &lt;feed&gt;Article3&lt;/feed&gt;&lt;br /&gt;2 AZ2&amp;#xa0; &lt;feed&gt;Article4&lt;/feed&gt;&lt;br /&gt;2 AZ2&amp;#xa0; &lt;feed&gt;Article5&lt;/feed&gt;&lt;br /&gt;3 AZ3&amp;#xa0; &lt;feed&gt;Article6&lt;/feed&gt;&lt;br /&gt;3 AZ3&amp;#xa0; &lt;feed&gt;Article7&lt;/feed&gt;&lt;br /&gt;3 AZ3&amp;#xa0; &lt;feed&gt;Article8&lt;/feed&gt;&lt;/code&gt;&lt;p&gt;Comodo per unire il risultato di più record dei campi &lt;em&gt;xml&lt;/em&gt;, no? Boh!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/Database/" rel="tag"&gt;Database&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/SQL_Server/" rel="tag"&gt;SQL Server&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2523/Cross-Apply-Campi-XML.aspx"&gt;&lt;em&gt;Cross apply con i campi XML&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>Memo, Database, SQL Server</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2523/Cross-Apply-Campi-XML.aspx</guid><slash:comments>0</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2523/Cross-Apply-Campi-XML.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2523.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2523</trackback:ping></item><item><title>Disabilitare tutti i web control in una pagina.</title><link>http://blogs.aspitalia.com/az/post2522/Disabilitare-Web-Control-Pagina.aspx</link><pubDate>Wed, 08 Jul 2009 12:21:10 GMT</pubDate><description>&lt;img src="http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2522" border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Visto che mi serve spesso, ecco un po' di veloce codice:&lt;/p&gt; &lt;p&gt;&lt;em&gt;CallAllWebControl&amp;lt;Button&amp;gt;(this.Page, action =&amp;gt; action.Enabled = false); &lt;br /&gt;CallAllWebControl&amp;lt;TextBox&amp;gt;(this.Page, action =&amp;gt; action.Enabled = false);&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;public void CallAllWebControl&amp;lt;T&amp;gt;(Control controls, Action&amp;lt;T&amp;gt; method) where T:Control &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Action&amp;lt;Control, Action&amp;lt;T&amp;gt;&amp;gt; fun = null; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fun = (c, MethodX) =&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (c.GetType()==typeof(T)) MethodX((T)c); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; foreach (Control item in c.Controls) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fun(item, method); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fun(controls, method); &lt;br /&gt;} &lt;/em&gt;&lt;/p&gt; &lt;p&gt;Utile anche nel caso volessi &lt;em&gt;check-are&lt;/em&gt; tutti i checkbox nella pagina:&lt;/p&gt; &lt;p&gt;&lt;em&gt;CallAllWebControl&amp;lt;CheckBox&amp;gt;(this.Page, action =&amp;gt; action.Checked = true);&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Non è ottimizzatissimo, ma fa bene il suo lavoro.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/.NET_Framework/" rel="tag"&gt;.NET Framework&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/.NET_Framework_3.0/" rel="tag"&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/.NET_Framework_3.5/" rel="tag"&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/.NET_Framework_4.0/" rel="tag"&gt;.NET Framework 4.0&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Continua a leggere &lt;a href="http://blogs.aspitalia.com/az/post2522/Disabilitare-Web-Control-Pagina.aspx"&gt;&lt;em&gt;Disabilitare tutti i web control in una pagina&amp;amp;hellip;&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2013 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Andrea Zani</dc:creator><category>.NET4, .NET Framework, .NET Framework 3.0, .NET Framework 3.5, .NET Framework 4.0</category><guid isPermaLink="true">http://blogs.aspitalia.com/az/post2522/Disabilitare-Web-Control-Pagina.aspx</guid><slash:comments>3</slash:comments><wfw:comment>http://blogs.aspitalia.com/az/post2522/Disabilitare-Web-Control-Pagina.aspx#feedback</wfw:comment><wfw:commentRss>http://blogs.aspitalia.com/az/CommentRSS2522.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2522</trackback:ping></item></channel></rss>