<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Découvrons DotNet sur différentes plateformes</title>
	<atom:link href="https://blog.developpez.com/insideqt/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/insideqt</link>
	<description></description>
	<lastBuildDate>Sun, 28 Dec 2014 15:50:37 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>PCL et dependences</title>
		<link>https://blog.developpez.com/insideqt/p12812/xamarin-forms/pcl-et-dependences</link>
		<comments>https://blog.developpez.com/insideqt/p12812/xamarin-forms/pcl-et-dependences#comments</comments>
		<pubDate>Sun, 28 Dec 2014 15:50:37 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[PCL]]></category>
		<category><![CDATA[Xamarin.Forms]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/insideqt/?p=34</guid>
		<description><![CDATA[PCL = Portable class Library Pour pouvoir dans un projet PCL accèder aux API d&#8217;un système, il faut utiliser un système de dépendances. Vous avez plusieurs solutions liées à des interfaces ou à des classes abstraites/virtuelles aux choix Créer une classe avec des références sur des classes implémentant des interfaces Utiliser le DependencyService de Xamarin pour plateforme mobile référencant la librairie Xamarin Créer votre propre DependencyService multi plateforme Je privilégie la solution 1 et 3. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>PCL = Portable class Library<br />
Pour pouvoir dans un projet PCL accèder aux API d&rsquo;un système, il faut utiliser un système de dépendances.</p>
<p>Vous avez plusieurs solutions liées à des interfaces ou à des classes abstraites/virtuelles aux choix</p>
<ul>
<li>Créer une classe avec des références sur des classes implémentant des interfaces</li>
<li>Utiliser le  <a href="http://developer.xamarin.com/guides/cross-platform/xamarin-forms/dependency-service/" title="Aide" target="_blank">DependencyService de Xamarin pour plateforme mobile référencant la librairie Xamarin</a></li>
<li>Créer votre propre DependencyService multi plateforme</li>
</ul>
<p>Je privilégie la solution 1 et 3. La solution DependencyService de Xamarin ne me plaît pas car elle ne fonctionne pas pour les projets PC.</p>
<p>Je vous expose donc la solution 1 et 3.</p>
<p><strong>Solution 1</strong> avec une classe et un sorte de singleton renseigné par l&rsquo;application cible (et non par sa propre classe):</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">public class IO<br />
{<br />
&nbsp; &nbsp;private static IO _current = null;<br />
&nbsp; &nbsp;public static IO Current<br />
&nbsp; &nbsp;{<br />
&nbsp; &nbsp; &nbsp;get { return _current; }<br />
&nbsp; &nbsp; &nbsp;set { _current = value; }<br />
&nbsp; &nbsp;}<br />
&nbsp; &nbsp;public virtual bool FichierExiste(string cheminFichier)<br />
&nbsp; &nbsp;{<br />
&nbsp; &nbsp; &nbsp;return false; // Vous pouvez aussi lever une exception pour indiquer que le code n'a pas été implémenté<br />
&nbsp; &nbsp;}<br />
}<br />
<br />
public class IOiOS : IO<br />
{<br />
&nbsp; &nbsp;public override bool FichierExiste(string cheminFichier)<br />
&nbsp; &nbsp;{<br />
&nbsp; &nbsp; &nbsp;return File.Exists(cheminFichier);<br />
&nbsp; &nbsp;}<br />
}</div></div>
<p>pour l&rsquo;utiliser, il suffit de faire un<br />
IO.Current = new IOiOS();<br />
puis dans le PCL : IO.Current.FichierExiste(&laquo;&nbsp;image.png&nbsp;&raquo;);</p>
<p><strong>Solution 3</strong><br />
Créer votre propre DependencyService</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">using System.Reflection;<br />
using System.Text;<br />
using System.Threading.Tasks;<br />
<br />
namespace Aktaour.Core.Framework<br />
{<br />
&nbsp; &nbsp; public class DependencyInjector<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; private static DependencyInjector _instance = null;<br />
&nbsp; &nbsp; &nbsp; &nbsp; private Dictionary&amp;lt;Type,Type&amp;gt; _dependencyList = new Dictionary&amp;lt;Type,Type&amp;gt;();<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; public static DependencyInjector Instance<br />
&nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (_instance == null)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _instance = new DependencyInjector();<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return _instance;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; public void Register&amp;lt;TBase,T&amp;gt;() where T : TBase<br />
&nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (_dependencyList.ContainsKey(typeof(TBase)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new Exception(&quot;Type already register&quot;);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _dependencyList.Add(typeof(TBase), typeof(T));<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; public TBase Get&amp;lt;TBase&amp;gt;()<br />
&nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (_dependencyList.ContainsKey(typeof(TBase)))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (TBase)Activator.CreateInstance(_dependencyList[typeof(TBase)]);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return default(TBase);<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; }<br />
}</div></div>
<p>Dans le projet PCL créer une classe IO</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">public class IO<br />
{<br />
&nbsp; &nbsp;public virtual bool FichierExiste(string cheminFichier)<br />
&nbsp; &nbsp;{<br />
&nbsp; &nbsp; &nbsp;return false; // Vous pouvez aussi lever une exception pour indiquer que le code n'a pas été implémenté<br />
&nbsp; &nbsp;}<br />
}</div></div>
<p>Et dans votre application iOS créer une classe IOiOS</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">public class IOiOS : IO<br />
{<br />
&nbsp; &nbsp;public override bool FichierExiste(string cheminFichier)<br />
&nbsp; &nbsp;{<br />
&nbsp; &nbsp; &nbsp;return File.Exists(cheminFichier);<br />
&nbsp; &nbsp;}<br />
}</div></div>
<p>et enregistrer votre classe dans le DependencyInjector</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">DependencyInjector.Instance.Register();</div></div>
<p>Ensuite, pour créer vos objets, vous utilisez le DependencyInjector via la classe de base</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">IOiOS io = DependencyInjector.Instance.Get&amp;lt;IO&amp;gt; ();</div></div>
<p>Pour finir, il suffit d&rsquo;être inventif pour coller au plus à vos besoins.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiplateforme, MVVM, PCL, Xamarin.Forms</title>
		<link>https://blog.developpez.com/insideqt/p12811/xamarin-forms/multiplateforme-mvvm-pcl-xamarin-forms</link>
		<comments>https://blog.developpez.com/insideqt/p12811/xamarin-forms/multiplateforme-mvvm-pcl-xamarin-forms#comments</comments>
		<pubDate>Sun, 28 Dec 2014 14:13:11 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[MVVM]]></category>
		<category><![CDATA[PCL]]></category>
		<category><![CDATA[Xamarin.Forms]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/insideqt/?p=16</guid>
		<description><![CDATA[Pour l&#8217;écriture d&#8217;un logiciel multi-plateforme PC et mobile, j&#8217;utilise des techniques qui sont nouvelles pour moi et qui m&#8217;oblige à remettre en question mes acquis de développeur mono plateforme. Pour écrire un logiciel sur plusieurs plateformes, il faut un langage de programmation commun, un ou plusieurs EDI compatible et une logique de programmation qui ne dépend pas de la machine cible. J&#8217;ai retenu: EDI visual studio Community 2013 (gratuit) et Xamarin Studio (avec licence indie) [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Pour l&rsquo;écriture d&rsquo;un logiciel multi-plateforme PC et mobile, j&rsquo;utilise des techniques qui sont nouvelles pour moi et qui m&rsquo;oblige à remettre en question mes acquis de développeur mono plateforme.</p>
<p>Pour écrire un logiciel sur plusieurs plateformes, il faut un langage de programmation commun, un ou plusieurs EDI compatible et une logique de programmation qui ne dépend pas de la machine cible.</p>
<p>J&rsquo;ai retenu:</p>
<ul>
<li>EDI visual studio Community 2013 (gratuit) et Xamarin Studio (avec licence indie)</li>
<li>Le langage de programmation C# basé sur le frameWork 4.5 avec les mots clés aync/await</li>
<li>Des projets multi plateformes PCL</li>
<li>le pattern de programmation MVVM</li>
<li>un PC sous Windows 8.1</li>
<li>un Mac pour l&rsquo;émulateur iOS, et pour le développement sous un device Android (ici un galaxy note 1) </li>
</ul>
<p><em><strong>MVVM</strong></em><br />
Le pattern Modèle-Vue-VueModèle est un pattern qui veut séparer la vue de la logique et de l&rsquo;accès aux données en accentuant les principes de binding et des événements.<br />
Vous écrivez dans le viewModel et le résultat s&rsquo;affiche dans la vue à l&rsquo;aide de Binding et la vue interagit avec le viewModel par des événements. et enfin le viewModel agit sur les données en bdd/fichier directement.</p>
<p>C&rsquo;est simple et efficace.</p>
<p><em><strong>PCL</strong></em><br />
Le but du PCL (portable class library) est donc de créer différentes librairies indépendantes de chaque plateforme et de créer un projet pour chaque plateforme cible.<br />
Chaque projet PCL a accès à un framework .Net inter plateforme mais limité par ses fonctionnalités. Toutes dll qui n&rsquo;est pas multiplateforme et indépendant du systèmes y est rejetés.</p>
<p>En résumé:</p>
<ul>
<li>un projet library PCL nommé &laquo;&nbsp;Message&nbsp;&raquo; qui contiendra vos classes strictement de stockage de données en mémoire</li>
<li>un projet library PCL nommé &laquo;&nbsp;Core&nbsp;&raquo; qui contiendra votre logique applicative, vos viewModel (pour le MVVM)</li>
<li>un projet library PCL nommé &laquo;&nbsp;DesktopCore&nbsp;&raquo; qui contiendra les view WPF et les viewmodel dérivés de ceux du projet Core</li>
<li>un projet library PCL nommé &laquo;&nbsp;MobileCore&nbsp;&raquo; qui contiendra les view Xamarin.Forms et les viewmodel dérivés de ceux du projet Core</li>
<li>un projet application WPF nommé &laquo;&nbsp;DesktopApp&nbsp;&raquo; qui contiendra le premier formulaire et l&rsquo;accès aux fichiers et aux APi du système PC</li>
<li>un projet application Android nommé &laquo;&nbsp;AndroidApp&nbsp;&raquo; qui contiendra le premier formulaire et l&rsquo;accès aux fichiers et aux APi du système Android</li>
<li>un projet application Windows Phone nommé &laquo;&nbsp;WPApp&nbsp;&raquo; qui contiendra le premier formulaire et l&rsquo;accès aux fichiers et aux APi du système Windows Phone</li>
<li>un projet application Windows Phone nommé &laquo;&nbsp;iOSApp&nbsp;&raquo; qui contiendra le premier formulaire et l&rsquo;accès aux fichiers et aux APi du système iOS</li>
</ul>
<p>Sur le papier, en lisant des articles je me suis dit hourra, trop facile. <strong>La réalité est bien plus compliquée!</strong></p>
<p>Comme je vous l&rsquo;ai annoncé (vous avez le droit de ne pas me croire) pour faire du multi plateforme, il faut être décoléré du système cible.<br />
Vous devez vous concentrer sur une notion: &laquo;&nbsp;Ne t&rsquo;occupes pas de comment accéder aux API systèmes, part du principe qu&rsquo;ils ne sont pas accessibles&nbsp;&raquo;.<br />
En gros, ne comptes pas sur le système pour t&rsquo;aider, tu es le seul à pouvoir y accéder et cela par tes propres moyens.</p>
<p>Je m&rsquo;explique: prenez l&rsquo;exemple d&rsquo;un test d&rsquo;existence d&rsquo;un fichier.</p>
<ul>
<li>Sous Windows, Android, iOS
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">File.Exists(nomFichier);</div></div>
</li>
<li>Sous Windows Phone:
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">StorageFolder appFolder = ApplicationData.Current.LocalFolder;<br />
var files = Task.Run(async () =&amp;gt; await appFolder.GetFilesAsync()).GetAwaiter().GetResult();<br />
var file = files.Where(t =&amp;gt; t.Name == nomFichier).FirstOrDefault();<br />
result = file != null;</div></div>
</li>
</ul>
<p>Mais pourquoi Microsoft nous a pondu une merde pareil sur Windows Phone, je sais pas, c&rsquo;est chiant mais vu que l&rsquo;on fait du PCL on s&rsquo;en moque!</p>
<p>En effet, qui dit library PCL, dit impossibilité d&rsquo;accéder à File.Exists ou à StorageFolder /StorageFile. il faut passer par sont propres systèmes de dépendances via des pointeurs qui références des objets liés à chaque plateforme.</p>
<p><em><strong>Xamarin.Forms</strong></em><br />
Le frameWork Xamarin.Forms est tout nouveau, créé mi 2014 par la société Xamarin (enfin créé par un développeur puis récupéré par Xamarin&#8230;).<br />
Il ambitionne de révolutionner la manière dont vous écrivez des interfaces graphiques pour le développement mobile.<br />
Ecrivez une fois (pour iOS) et visualisez partout (WinPhone/Android/iOS).<br />
<a href="http://xamarin.com/forms" title="Xamarin.Forms" target="_blank">Xamarin.Forms</a></p>
<p>Il y a un gros Hic tout de même, Xamarin.Forms permet de faire de belles choses mais il est loin d&rsquo;être parfait et toujours en chantier actuellement. Des versions sortent toutes les semaines.<br />
Des bugs apparaissent, d&rsquo;autres disparaissent mais on peut toujours s&rsquo;en sortir en laissant certaines choses de temporairement de cotées. </p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Découvrons Xamarin.Forms</title>
		<link>https://blog.developpez.com/insideqt/p12810/xamarin-forms/decouvrons-xamarin-forms</link>
		<comments>https://blog.developpez.com/insideqt/p12810/xamarin-forms/decouvrons-xamarin-forms#comments</comments>
		<pubDate>Sun, 28 Dec 2014 11:42:05 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[Xamarin.Forms]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/insideqt/?p=11</guid>
		<description><![CDATA[Suite à 2 années de travail acharné sur une application de vente et d&#8217;aide à la vente pour le retail sous Xamarin.iOS (iOS 5.1 et supérieur). Je ne suis pas indépendant, je travaille pour une société éditrice de logicielle liée au retail. iStoreAssistant L&#8217;application en question s’exécute sous iOS et utilise différents matériels essentiellement pour des besoins spécifiques liés à l&#8217;activité du retail. un pinpad monétique : l&#8217;iSMP (paiement monétique). des imprimantes de caisses de [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Suite à 2 années de travail acharné sur une application de vente et d&rsquo;aide à la vente pour le retail sous Xamarin.iOS (iOS 5.1 et supérieur).<br />
Je ne suis pas indépendant, je travaille pour une société éditrice de logicielle liée au retail.<br />
<a href="http://www.cylande.com/web/blog/article/l-encaissement-mobile--une-evidence-en-magasin./70049" title="iStoreAssistant">iStoreAssistant</a></p>
<p>L&rsquo;application en question s’exécute sous iOS et utilise différents matériels essentiellement pour des besoins spécifiques liés à l&rsquo;activité du retail.</p>
<ul>
<li>un pinpad monétique : l&rsquo;iSMP (paiement monétique).</li>
<p><a href="http://blog.developpez.com/insideqt/files/2014/12/ismp_w605.jpg"><img src="http://blog.developpez.com/insideqt/files/2014/12/ismp_w605-300x179.jpg" alt="ismp" width="300" height="179" class="alignnone size-medium wp-image-13" /></a></p>
<li>des imprimantes de caisses de type Epson POS</li>
<p><a href="http://blog.developpez.com/insideqt/files/2014/12/shopping.jpg"><img src="http://blog.developpez.com/insideqt/files/2014/12/shopping-300x300.jpg" alt="tm-t88V" width="300" height="300" class="alignnone size-medium wp-image-14" /></a></p>
<li>un lecteur de code barre (soit iSMP, soit Captuvo SL22) </li>
<p><a href="http://blog.developpez.com/insideqt/files/2014/12/captuvosl22v5_01_large.png"><img src="http://blog.developpez.com/insideqt/files/2014/12/captuvosl22v5_01_large-300x300.png" alt="captuvosl22" width="300" height="300" class="alignnone size-medium wp-image-12" /></a>
</ul>
<p>Le but des différents billets qui vont suivre est d&rsquo;appliquer les différentes méthodes qui m&rsquo;ont permis de créer ce logiciel monoplateforme (sous iOS) pour en faire un logiciel multiplateforme (mobile iOS, Android, Windows phone et PC).<br />
Pour cela, je m&rsquo;oriente aujourd&rsquo;hui vers <strong>Xamarin.Forms</strong>.</p>
<p><strong>Xamarin.Forms</strong> est une surcouche graphique multiplateforme mobile garantissant un rendu graphique similaire sous iOS, Android et Windows phone.</p>
<p>Très intéressant sur le papier, vous écrivez en code C# ou en Xaml (fichier XML d&rsquo;interface) et vous obtenez votre interface graphique.</p>
<p>Si vous avez déjà écrit des logiciels WPF, vous ne serez pas &laquo;&nbsp;trop&nbsp;&raquo; dépaysé.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Mono]Asynchrone Mon meilleur ennemi</title>
		<link>https://blog.developpez.com/insideqt/p10605/mono-for-android/asynchrone_mon_meilleur_ennemi</link>
		<comments>https://blog.developpez.com/insideqt/p10605/mono-for-android/asynchrone_mon_meilleur_ennemi#comments</comments>
		<pubDate>Wed, 21 Dec 2011 23:27:57 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[Mono for Android]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Tout fier, je me lance dans ma première application à l&#8217;aide de Mono for Android. Je crée un projet sous Visual Studio 2010 et me munis de mon téléphone sous Android. Pour les imprimes écrans, j&#8217;utilise l&#8217;option screen capture du logiciel ddms (dalvik debug monitor) fournit avec le sdk de mono. L&#8217;application à créer est simple: Ouverture d&#8217;une activité à partir d&#8217;un bouton Fermeture de l&#8217;activité ouverte Affichage d&#8217;un message à l&#8217;écran sur fermeture de [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Tout fier, je me lance dans ma première application à l&rsquo;aide de Mono for Android.</p>
<p>Je crée un projet sous Visual Studio 2010 et me munis de mon téléphone sous Android.<br />
Pour les imprimes écrans, j&rsquo;utilise l&rsquo;option screen capture du logiciel ddms (dalvik debug monitor) fournit avec le sdk de mono.</p>
<p>L&rsquo;application à créer est simple: </p>
<ul>
<li>Ouverture d&rsquo;une activité à partir d&rsquo;un bouton</li>
<li>Fermeture de l&rsquo;activité ouverte</li>
<li>Affichage d&rsquo;un message à l&rsquo;écran sur fermeture de la seconde activité. </li>
</ul>
<p><span id="more-6"></span></p>
<p>Dans une application standard, la logique reviendrait à exécuter un écran modal et après la fermeture de l&rsquo;écran, on afficherait le message. Ce qui donnerai en C#:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">void MaLoquique() <br />
{ <br />
&nbsp; Form ecran2 = new Form(); <br />
&nbsp; ecran2.ShowModal(); <br />
&nbsp; MessageBox.Show(&quot;mon message&quot;); <br />
}</div></div>
<p>En Mono for Android, cela donnerait:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">void MaLoquique() <br />
{ <br />
&nbsp;this.StartActivity(typeof(ecran2)); <br />
&nbsp;Toast.MakeText(this, &quot;Mon message&quot;, ToastLength.Short).Show(); <br />
}</div></div>
<p>Et là surprise&#8230; l&rsquo;activité se lance et on voit le message s&rsquo;afficher en même temps. Que passa???<br />
En lisant la documentation du Android SDK et en surfant, j&rsquo;arrive à la conclusion qu&rsquo;Android est entièrement asynchrone.</p>
<p>Pour ceux qui connaisse un peu Flex, c&rsquo;est la même &laquo;&nbsp;bordel&nbsp;&raquo;, il faut tout synchroniser dans un evenement global.</p>
<p>Cet événement global est expliqué sur beaucoup de site et cela fonctionne bien pour une petite application qui n&rsquo;a beaucoup d&rsquo;écran imbriqué.</p>
<p>Parlons maintenant du synchronise entre deux threads, si un thread doit attendre la fin d&rsquo;un autre Thread pour continuer son traitement. Comment faire?<br />
Un novice ferait une boucle d&rsquo;attente comme un while. Les développeurs utiliseront un mutex ou un sémaphore.<br />
exemple: thread1 lance le thread2 et thread1 attends la liberation du jeton du mutex.<br />
Pour celà j&rsquo;utilise l&rsquo;objet &laquo;&nbsp;AutoResetEvent&nbsp;&raquo;.</p>
<p>Pour en revenir à notre application, je vais appliquer ceprincipe sans passer par l&rsquo;événement global.<br />
Pour cela il faudra créer l&rsquo;écran2 dans un Thread. En effet si je bloque le mutex dans le thread principal, votre application est figé!<br />
Dans l&rsquo;écran2, j&rsquo;ai mis un AutoResetEvent en static</p>
<p>Activité principale:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">void MaLoquique() <br />
{ <br />
&nbsp; Thread t = new Thread(() =&gt; <br />
&nbsp;{ <br />
&nbsp; &nbsp;this.StartActivity(typeof(ecran2)); <br />
&nbsp;<br />
&nbsp; &nbsp;ecran2.MonMutex.WaitOne(); <br />
&nbsp;<br />
&nbsp; &nbsp;this.RunOnUiThread(() =&gt; <br />
&nbsp; &nbsp;{ <br />
&nbsp; &nbsp; &nbsp; Toast.MakeText(this, &quot;Mon message&quot;, ToastLength.Short).Show(); <br />
&nbsp; &nbsp;}); <br />
&nbsp;}); <br />
&nbsp;t.Start(); <br />
}</div></div>
<p>Ecran2:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; [Activity(Label = &quot;ecran2&quot;)] <br />
&nbsp; &nbsp; public class ecran2 : Activity <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; public static AutoResetEvent MonMutex = new AutoResetEvent(false); <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; protected override void OnCreate(Bundle bundle) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; base.OnCreate(bundle); <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Create your application here <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; protected override void OnDestroy() <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; base.OnDestroy(); <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MonMutex.Set(); <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; }</div></div>
<p>le &laquo;&nbsp;RunOnUiThread&nbsp;&raquo; sert à intéragir avec le thread de l&rsquo;activité en cours, néccessaire pour intéragir avec des élément graphiques.</p>
<p>Le miracle opère, le message s&rsquo;affiche après la fermeture de l&rsquo;écran2.</p>
<p>Dans le prochain billet, je décrirai un processus plus complet pour passer des variables et les mutex sur chaque activity lancés.</p>
<p><a href="http://dl.dropbox.com/u/40788674/tutomonoforandroid/appAsynchrone.zip">Voici le code source lié à ce billet</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[Mono]Asynchrone Mon meilleur ennemi (suite)</title>
		<link>https://blog.developpez.com/insideqt/p10611/mono-for-android/title_213</link>
		<comments>https://blog.developpez.com/insideqt/p10611/mono-for-android/title_213#comments</comments>
		<pubDate>Sun, 25 Dec 2011 11:32:59 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[Mono for Android]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Il y a quelques jours j&#8217;exposai vulgairement ma façon de développer en ansynchrone entre différentes activity. Aujourd&#8217;hui je vous montre comment faire en mutualisant la génération des mutex et des paramètres passés entre activity. Pour cela , je crée: Une classe static nommée BibFrm (Bibliothèque pour les fomulaires) qui contiendra une liste de paramètres liée à chaque activity par un identifiant. Une classe nommé ParamFrm qui contiendra les paramètres (cle/valeur) de mon activity Un objet [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Il y a quelques jours j&rsquo;exposai vulgairement ma façon de développer en ansynchrone entre différentes activity.</p>
<p>Aujourd&rsquo;hui je vous montre comment faire en mutualisant la génération des mutex et des paramètres passés entre activity.</p>
<p>Pour cela , je crée:</p>
<ul>
<li>Une classe static nommée BibFrm (Bibliothèque pour les fomulaires) qui contiendra une liste de paramètres liée à chaque activity par un identifiant.</li>
<li>Une classe nommé ParamFrm qui contiendra les paramètres (cle/valeur) de mon activity</li>
<li>Un objet pour accéder de manière unique à mes paramètres (Univers Threadé) nommé mutexParamFrm</li>
<li>Une fonction de recupération de paramètres généric</li>
<li>Une fonction de suppression complète de paramètres</li>
<li>Une fonction d&rsquo;ajout de paramètres</li>
<li>Une fonction de calcul du prochain identifiant des activity</li>
</ul>
<p><span id="more-7"></span></p>
<p>La génération des identifiants des activity. Noté que l&rsquo;objet mutexParamFrm sert à locker l&rsquo;accès interThread a une seul iteration à la fois.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; public static object mutexParamFrm = new object(); <br />
&nbsp; &nbsp; private static int idFrm = 0; <br />
&nbsp; &nbsp; public static int ProchainIdFrm() <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; int result = 1; <br />
&nbsp; &nbsp; lock (mutexParamFrm) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (idFrm == Int32.MaxValue) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; idFrm = 1; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; idFrm++; <br />
&nbsp; &nbsp; &nbsp; result = idFrm; <br />
&nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; return result; <br />
&nbsp; &nbsp; }</div></div>
<p>La classe contenant les paramètres</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; internal class ParamFrm <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; public string Cle = string.Empty; <br />
&nbsp; &nbsp; &nbsp; &nbsp; public object Obj = null; <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; public ParamFrm() <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; public ParamFrm(string cle, object obj) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Cle = cle; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Obj = obj; <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; }</div></div>
<p>La fonction de récupération de paramètres</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; public static List&lt;ParamFrm&gt; recupListeParamFrm(int idFrm) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List&lt;ParamFrm&gt; listeParam = null; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (listeParamDesFrm.ContainsKey(idFrm)) // récupération de la liste des paramètres par rapport à la clé <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listeParam = listeParamDesFrm[idFrm]; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listeParam = new List&lt;ParamFrm&gt;(); // génération de la liste si non présent <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listeParam.Add(new ParamFrm(&quot;mutexfrm&quot;, new AutoResetEvent(false))); //ajout auto du mutex pour bloquer les activity parentes <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listeParamDesFrm.Add(idFrm, listeParam); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return listeParam; <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; public static bool recupParamFrm&lt;T&gt;(int idFrm, string nomParam, out T obj) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bool result = false; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj = default(T); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nomParam = nomParam.ToLower(); <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lock (lockParamFrm) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List&lt;ParamFrm&gt; listeParam = recupListeParamFrm(idFrm); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach (ParamFrm paramFrm in listeParam) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (paramFrm.Cle == nomParam) //la cle est toutjours un minuscule <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = true; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj = (T)paramFrm.Obj; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return result; <br />
&nbsp; &nbsp; &nbsp; &nbsp; }</div></div>
<p>La fonction de vidage des paramètres</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; public static void viderParamFrm(int idFrm) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lock (lockParamFrm) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (listeParamDesFrm.ContainsKey(idFrm)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listeParamDesFrm.Remove(idFrm); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; }</div></div>
<p>La fonction d&rsquo;ajout de paramètres</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; public static void ajouteParamFrm(int idFrm, string nomParam, object obj) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nomParam = nomParam.ToLower(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lock (lockParamFrm) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List&lt;ParamFrm&gt; listeParam = recupListeParamFrm(idFrm); <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bool trouve = false; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach (ParamFrm paramFrm in listeParam) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (paramFrm.Cle == nomParam) //la cle est toutjours un minuscule <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; trouve = true; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; paramFrm.Obj = obj; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!trouve) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listeParam.Add(new ParamFrm(nomParam, obj)); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; }</div></div>
<p>Pour plus de clareté, je lance l&rsquo;activité &laquo;&nbsp;ecran2&Prime; dans sa propre class par la méthode static Afficher:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; public static void Afficher(Activity activity, string titre) <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; object obj; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int idFrm = BibFrm.ProchainIdFrm(); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (BibFrm.recupParamFrm(idFrm, BibFrm.nomParamMutexFrm, out obj)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BibFrm.ajouteParamFrm(idFrm, &quot;titre&quot;, titre); <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AutoResetEvent a = (AutoResetEvent)obj; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Intent intent = new Intent(activity, typeof(ecran2)); <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; activity.RunOnUiThread(() =&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; intent.PutExtra(&quot;idfrm&quot;, idFrm); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; activity.StartActivity(intent); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a.WaitOne(); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BibFrm.viderParamFrm(idFrm); <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; }</div></div>
<p>Chaque paramètre sera ajouté dans la liste des paramètres customisé. Je ne préfère pas utiliser les Itent car il est impossible de leur passer des objets complexes sans les sérialiser.<br />
L&rsquo;itent est utilisé uniquement pour sauvegarder l&rsquo;identifiant de la fenetre.</p>
<p>Dès lors, le thread est bloqué et attends la fermeture de l&rsquo;activité.<br />
Pour les plus codeurs d&rsquo;entre vous, vous pouvez mettre tout ce code dans une activité parente et dérivé toutes vos activity de celle ci et le tour est joué.</p>
<p>Bonne fêtes de fin d&rsquo;année.</p>
<p><a href="http://dl.dropbox.com/u/40788674/tutomonoforandroid/appAsynchronegeneralise.zip">Voici le code source lié à ce billet</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Mono]Orientation de l&#8217;écran</title>
		<link>https://blog.developpez.com/insideqt/p10614/mono-for-android/orientation_de_l_ecran</link>
		<comments>https://blog.developpez.com/insideqt/p10614/mono-for-android/orientation_de_l_ecran#comments</comments>
		<pubDate>Mon, 26 Dec 2011 10:11:33 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[Mono for Android]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Sur Android, l&#8217;orientation de l&#8217;écran influe sur l&#8217;affichage des applications. L&#8217;Android SDK offre la possibilité aux écrans de s&#8217;adapter à la résolution par ces systèmes de gravité (sorte de point d&#8217;ancrage). Je crée mon application et je m&#8217;amuse à la passer du mode portrait au mode paysage. Cette application se connecte en TCP à mon PC, et rapidement je me suis rendu compte que mon application se comporte étrangement. En effet, à chaque changement d&#8217;orientation, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Sur Android, l&rsquo;orientation de l&rsquo;écran influe sur l&rsquo;affichage des applications.<br />
L&rsquo;Android SDK offre la possibilité aux écrans de s&rsquo;adapter à la résolution par ces systèmes de gravité (sorte de point d&rsquo;ancrage).<br />
Je crée mon application et je m&rsquo;amuse à la passer du mode portrait au mode paysage.<br />
Cette application se connecte en TCP à mon PC, et rapidement je me suis rendu compte que mon application se comporte étrangement.</p>
<p>En effet, à chaque changement d&rsquo;orientation, ma connexion TCP se renouvelle. Après plusieurs heures d&rsquo;analyses et de recherches j&rsquo;ai compris et résolu le problème.</p>
<p>Par défaut, à chaque changement d&rsquo;orientation, l&rsquo;Activity courante est détruite puis recréé par le système Android.<br />
Imaginez ma frustration en constatant cela, où sont mes objets en mémoires -> disparu&#8230;.</p>
<p>Je connais deux solutions à ce problème:</p>
<ul>
<li>Surcharger la méthode onRetainNonConfigurationInstance pour en sauvegarder un seul objet. Je dé-conseil ce n&rsquo;est vraiment pas pratique</li>
<li>Surchager la méthode OnConfigurationChanged</li>
</ul>
<p>Le fait de surcharger la méthode OnConfigurationChanged et de définir la propriété ConfigurationChanges au Manifeste permet de ne plus redémarrer l&rsquo;activité courante en cas de changement d&rsquo;orientation.</p>
<p>TIPs: en java, les propriétés ConfigurationChanges se trouve dans le fichier AndroidManifest.xml du projet. Sous Mono for Android c&rsquo;est dans l&rsquo;entête de votre définition de la classe qu&rsquo;il se trouve.</p>
<p>Exemple:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[Activity(Label = &quot;FrmTest &quot;, ConfigurationChanges=Android.Content.PM.ConfigChanges.Orientation)] <br />
public class FrmTest : Activity <br />
{ <br />
&nbsp; /// &lt;summary&gt; <br />
&nbsp; /// Permet de ne plus redemarrer l'activité sur un changement de configuration <br />
&nbsp; /// &lt;/summary&gt; <br />
&nbsp; /// &lt;param name=&quot;newConfig&quot;&gt;&lt;/param&gt; <br />
&nbsp; public override void OnConfigurationChanged(Configuration newConfig) <br />
&nbsp; { <br />
&nbsp; &nbsp; base.OnConfigurationChanged(newConfig); <br />
&nbsp; } <br />
}</div></div>
<p>Cette petite astuce vous permettra sans doute de gagner du temps :).</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mono for Android</title>
		<link>https://blog.developpez.com/insideqt/p10603/mono-for-android/mono_for_android</link>
		<comments>https://blog.developpez.com/insideqt/p10603/mono-for-android/mono_for_android#comments</comments>
		<pubDate>Wed, 21 Dec 2011 21:15:03 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[Mono for Android]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Bonjour, Je suis passé d&#8217;un Iphone à un Samsung Note sous Android 2.3.6, je pars donc à la découverte de Mono for Android. Pour information, Mono for Android permet de développer des applications en C#. Il est basé sur le runtime Mono et est propriété de la société Xamarin . L&#8217;interface graphique est basé sur les fichiers axml de l&#8217;android sdk. Il est donc assez aisé de trouver de la documentation sur la partie graphique [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Bonjour,</p>
<p>Je suis passé d&rsquo;un Iphone à un Samsung Note sous Android 2.3.6, je pars donc à la découverte de Mono for Android.</p>
<p>Pour information, Mono for Android permet de développer des applications en C#. Il est basé sur le runtime Mono et est propriété de la société <a href="http://www.xamarin.com/">Xamarin </a>.</p>
<p>L&rsquo;interface graphique est basé sur les fichiers axml de l&rsquo;android sdk. Il est donc assez aisé de trouver de la documentation sur la partie graphique sur le <a href="http://developer.android.com/sdk/index.html"> site officiel</a>.</p>
<p><span id="more-5"></span></p>
<p>Ce qui va m&rsquo;intéresser pour le moment c&rsquo;est de comprendre et de détourner la logique du tout asynchrone de l&rsquo;Android SDK qui pour tout dire m’horripile grandement.<br />
L&rsquo;application se décompose en Activity, Widget et d&rsquo;autres choses que je ne connais pas encore.<br />
 -Les Activity sont les écrans de votre application.<br />
 -Les Widgets sont les composants utilisateurs affichés dans les Activity.</p>
<p>Pour ce qui est du développement, vous écrivez du code .Net en C# dans Visual Studio 2010 ou/et MonoDevelop sous Windows/Linux/MacOSX.</p>
<p>Un émulateur existe pour tester vos applications mais il est extrêmement long à la détente tout du moins sous Windows.<br />
La seule solution pour pouvoir développer correctement est d&rsquo;acheter une licence de développement (399 euros pour un développeur).<br />
Je sais que c&rsquo;est cher payé pour développer en C# alors que le développement en Java est totalement gratuit.</p>
<p>La puissance de Xamarin c&rsquo;est que le code hors écran est compatible sous Iphone/IPad. Il suffit de refaire les écrans de vos applications et de fusionner le code métier sous les différentes plateforme.</p>
<p>En poussant le vice, vous pouvez même avec une certaine organisation étendre cette réutilisation de code sous Windows PC/Mobile/Phone.</p>
<p>Par exemple pour mon entreprise, il y a plusieurs années j&rsquo;ai porté une application de vente écrite en C# CF (Windows mobile/CE) sous Windows XP. En réorganisant tout simplement l&rsquo;application, avec une directive de compilation.</p>
<p>Il y a quelques jours, je me suis mis en tête de récidiver en m&rsquo;attaquant à la plateforme Android. Pour ce faire, j&rsquo;ai bien évidemment choisi Mono for Android et après 3 soirées, j&rsquo;ai porté environ 80% du code métier en modifiant moins de 5% de sont code.<br />
Le plus gros changement fut au niveau des requetes vers la base de données. J&rsquo;ai du retravailler les requêtes et les connexions à la base pour utiliser une base SqLite au lieu de SQLCe database.</p>
<p>Une fois le code données et métier portés, je me suis attaqué à l&rsquo;interface graphique et la au mon Dieu &laquo;&nbsp;tout est asynchrone&nbsp;&raquo;</p>
<p>Quel casse tête!</p>
<p>Au fil des entrées du blog, je vous expliquerai comment contourner assez facilement le mode asynchrone pour le rendre synchrone.<br />
Beaucoup d&rsquo;entre vous me dirons que c&rsquo;est une hérésie, moi je parlerai plutôt de logique d&rsquo;application.<br />
Comme je le dis souvent, la simplicité est le maître mot de la durabilité. </p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>QML Cursor</title>
		<link>https://blog.developpez.com/insideqt/p9711/qml/qml_cursor</link>
		<comments>https://blog.developpez.com/insideqt/p9711/qml/qml_cursor#comments</comments>
		<pubDate>Wed, 26 Jan 2011 09:45:26 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[Qml]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Un petit billet pour vous montrer comment changer le curseur de la souris lors du survole d’un bouton dans une application Qt mixte C++/QML. Il n’existe apparemment pas de fonction QML pour changer le curseur de l’application, je vous propose donc de le faire manuellement. Résultat : Bibliothèque C++ : Je crée une classe de bibliothèque nommé Biblio. Dans cette classe, je crée une méthode AfficheCurseur qui récupère le nom du curseur et qui affiche [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Un petit billet pour vous montrer comment changer le curseur de la souris lors du survole  d’un bouton dans une application Qt mixte C++/QML.</p>
<p>Il n’existe apparemment pas de fonction QML pour changer le curseur de l’application, je vous propose donc de le faire manuellement.</p>
<p><b>Résultat :</b><br />
<img src="http://blog.developpez.com/media/Fenetre.png" width="244" height="96" alt="" /></p>
<p><span id="more-4"></span></p>
<p>Bibliothèque C++ :</p>
<p>Je crée une classe de bibliothèque nommé Biblio.<br />
Dans cette classe, je crée une méthode AfficheCurseur qui récupère le nom du curseur et qui affiche le curseur correspondant.</p>
<p><b>Biblio.h</b></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#ifndef BIBLIO_H <br />
#define BIBLIO_H <br />
#include &lt;QObject&gt; <br />
#include &lt;qdeclarative.h&gt; <br />
&nbsp;<br />
class Biblio : public QObject <br />
{ <br />
&nbsp; &nbsp; Q_OBJECT <br />
public: <br />
&nbsp; &nbsp; explicit Biblio(QObject *parent = 0); <br />
&nbsp; &nbsp; Q_INVOKABLE void AfficheCurseur(QString); <br />
signals: <br />
public slots: <br />
&nbsp;<br />
}; <br />
#endif // BIBLIO_H</div></div>
<p><b>Biblio.cpp</b></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#include &quot;biblio.h&quot; <br />
#include &lt;QtGui/QApplication&gt; <br />
#include &lt;QCursor&gt; <br />
&nbsp;<br />
Biblio::Biblio(QObject *parent) : <br />
&nbsp; &nbsp; QObject(parent) <br />
{ <br />
} <br />
void Biblio::AfficheCurseur(QString typeCurseur) <br />
{ <br />
&nbsp; &nbsp; QCursor curseur; <br />
&nbsp; &nbsp; if(typeCurseur.toUpper() == &quot;HAND&quot;) <br />
&nbsp; &nbsp; &nbsp; &nbsp; curseur = QCursor(Qt::PointingHandCursor); <br />
&nbsp; &nbsp; else <br />
&nbsp; &nbsp; &nbsp; &nbsp; curseur = QCursor(Qt::ArrowCursor); <br />
&nbsp; &nbsp; QApplication::setOverrideCursor(curseur); <br />
}</div></div>
<p><b>Connexion C++ vers QML :</b></p>
<p>Pour rendre accessible la méthode AfficheCurseur en QML, il faut référencer un objet Biblio dans l’objet QDeclarativeView.</p>
<p>Dans le fichier MainWindow.h, je crée mon objet Biblio.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">private: <br />
&nbsp; &nbsp; QDeclarativeView *ui; <br />
&nbsp; &nbsp; Biblio biblio;</div></div>
<p>Dans le fichier MainWindow.cpp j’ajoute la référence de mon objet Biblio sur le contexte du <b>QDeclarativeView</b>.<br />
Dans mon code QML, il sera appelable par le nom  donné dans la méthode <b>setContextProperty</b></p>
<p><code class="codecolorer text default"><span class="text">ui-&gt;rootContext()-&gt;setContextProperty(&quot;Biblio&quot;, &amp;biblio);</span></code></p>
<p><b>Création du composant Bouton :</b></p>
<p>Je m’appuie sur les boutons de l’exemple fourni dans Qt sdk 4.7 disponible à cette adresse<br />
<a href="http://doc.qt.nokia.com/4.7/demos-declarative-calculator.html"> </a></p>
<p>Je crée un fichier QML nommé Bouton.qml.<br />
Dans ce bouton, je crée une surface de capture d’événement de la souris MouseArea. Sur cette surface, je me connecte au signal onEntered et onExited qui respectivement capture l’entrée et la sortie du la souris sur la surface d’exposition.<br />
Attention, la propriété hoverEnabled doit être active, sinon l’événement est appelé uniquement lors du clique de la souris.</p>
<p>Sur ces signaux, j’appelle la fonction AfficheCurseur de mon objet Biblio.</p>
<p>Ce qui donne :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">import Qt 4.7 <br />
BorderImage { <br />
&nbsp; &nbsp; &nbsp;id: button <br />
&nbsp; &nbsp; &nbsp;property alias text: buttonText.text <br />
&nbsp; &nbsp; &nbsp;property alias font: buttonText.font <br />
&nbsp; &nbsp; &nbsp;property string color: &quot;&quot; <br />
&nbsp; &nbsp; &nbsp;property string hint: &quot;&quot; <br />
&nbsp; &nbsp; &nbsp;property int bordure: 8; <br />
&nbsp; &nbsp; &nbsp;property int tag: 0; <br />
&nbsp; &nbsp; &nbsp;signal boutonClick(int idBouton) <br />
&nbsp; &nbsp; &nbsp;source: &quot;images/button-&quot; + color + &quot;.png&quot;; clip: true <br />
&nbsp; &nbsp; &nbsp;border { left: 10; top: 10; right: 10; bottom: 10 } <br />
&nbsp; &nbsp; &nbsp;width: buttonText.width + bordure*2; <br />
&nbsp; &nbsp; &nbsp;Rectangle { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: shade <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;anchors.fill: button; radius: 10; color: &quot;black&quot;; opacity: 0 <br />
&nbsp; &nbsp; &nbsp;} <br />
&nbsp; &nbsp; &nbsp;Text { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: buttonText <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;anchors.centerIn: parent; anchors.verticalCenterOffset: -1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;font.pixelSize: 20; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;style: Text.Sunken; color: &quot;white&quot;; styleColor: &quot;black&quot;; smooth: true <br />
&nbsp; &nbsp; &nbsp;} <br />
&nbsp; &nbsp; &nbsp;MouseArea { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: mouseArea <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;anchors.fill: parent <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hoverEnabled: true <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;onClicked: { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;button.boutonClick(button.tag) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;onEntered: { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Biblio.AfficheCurseur(&quot;hand&quot;) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;onExited: { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Biblio.AfficheCurseur(&quot;none&quot;) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <br />
&nbsp; &nbsp; &nbsp;} <br />
&nbsp; &nbsp; &nbsp;states: State { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;name: &quot;pressed&quot;; when: mouseArea.pressed == true <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PropertyChanges { target: shade; opacity: .4 } <br />
&nbsp; &nbsp; &nbsp;} <br />
&nbsp;}</div></div>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installation Qt / Qt Creator / Qt Quick</title>
		<link>https://blog.developpez.com/insideqt/p9693/qml/installation_qt_qt_creator_qt_quick</link>
		<comments>https://blog.developpez.com/insideqt/p9693/qml/installation_qt_qt_creator_qt_quick#comments</comments>
		<pubDate>Fri, 21 Jan 2011 09:31:21 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[Qml]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le but de ce billet est de présenter l’installation de Qt, Qt creator et Qt Quick sur un environnement Windows XP. Mes Pré requis : Plateforme Windows Xp Installation de Qt SDK: Complete Development Environment 4.7.0 à partir de cette adresse : http://qt.nokia.com/downloads Doc d’installation Qt windows : http://doc.qt.nokia.com/latest/install-win.html Installation : J’installe Qt 4.7.0 dans le répertoire C:\Qt\2010.05 puis je renseigne la variable d’environnement %PATH%= … ; C:\Qt\2010.05\bin;C:\Qt\2010.05\qt\bin Je lance Qt Creator et j’obtiens ce [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le but de ce billet est de présenter l’installation de Qt, Qt creator et Qt Quick sur un environnement Windows XP.</p>
<p><b>Mes Pré requis :</b></p>
<ul>
<li>Plateforme Windows Xp</li>
<li>Installation de Qt SDK: Complete Development Environment 4.7.0 à partir de cette adresse : <a href="http://qt.nokia.com/downloads">http://qt.nokia.com/downloads</a></li>
<li>Doc d’installation Qt windows : <a href="http://doc.qt.nokia.com/latest/install-win.html">http://doc.qt.nokia.com/latest/install-win.html</a></li>
</ul>
<p><b>Installation :</b></p>
<p>J’installe Qt 4.7.0 dans le répertoire C:\Qt\2010.05 puis je renseigne la variable d’environnement %PATH%= … ; C:\Qt\2010.05\bin;C:\Qt\2010.05\qt\bin</p>
<p><span id="more-2"></span></p>
<p>Je lance Qt Creator et j’obtiens ce résultat.<br />
<img src="http://blog.developpez.com/media/QtCreator.png" width="800" height="625" alt="" /></p>
<p>Pour activer le designer de fenêtre QML, il faut activer le plugin dans QtCreator.<br />
Aller dans le menu « Aide/A propos des plugins » et dans la fenêtre « Plugins installés » il faut tout activer dans le sous menu « Qt Quick ».</p>
<p><img src="http://blog.developpez.com/media/pluginconf.png" width="658" height="427" alt="" /></p>
<p><b>Premier projet :</b></p>
<p>Pour tester la configuration, je crée un projet via la menu « Fichier/Nouveau Fichier ou projet » et sélectionner le type de projet « QML Application ».</p>
<p><img src="http://blog.developpez.com/media/NouvProjet.png" width="562" height="477" alt="" /></p>
<p>Je nomme le projet « InstallQml » et Qt Creator crée le projet.</p>
<p><b>Le code Qml ressemble à ceci :</b></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">import Qt 4.7 <br />
Rectangle { <br />
&nbsp; &nbsp; width: 200 <br />
&nbsp; &nbsp; height: 200 <br />
&nbsp; &nbsp; Text { <br />
&nbsp; &nbsp; &nbsp; &nbsp; x: 66 <br />
&nbsp; &nbsp; &nbsp; &nbsp; y: 93 <br />
&nbsp; &nbsp; &nbsp; &nbsp; text: &quot;Hello World&quot; <br />
&nbsp; &nbsp; } <br />
}</div></div>
<p>Si je clique sur le menu de gauche Design, j’obtiens le rendu de mon application :<br />
<img src="http://blog.developpez.com/media/DesignQml.png" width="800" height="625" alt="" /></p>
<p>Tout à l’air de bien fonctionner <img src="https://blog.developpez.com/insideqt/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
Edit: Ajout du chemin C:\Qt\2010.05\qt\bin dans la variable d&rsquo;environnement</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Traduction interface QML</title>
		<link>https://blog.developpez.com/insideqt/p9696/qml/traduction_interface_qml</link>
		<comments>https://blog.developpez.com/insideqt/p9696/qml/traduction_interface_qml#comments</comments>
		<pubDate>Fri, 21 Jan 2011 15:08:50 +0000</pubDate>
		<dc:creator><![CDATA[Aktaour]]></dc:creator>
				<category><![CDATA[Qml]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le but de ce billet est de tester l’internationalisation des applications QML. Je m’appuie sur la documentation Qt « QML Internationalization » disponible sur ce lien http://doc.qt.nokia.com/4.7-snapshot/qdeclarativei18n.html. Mot clés : L’internationalisation d’une application classique Qt passe par l’utilisation de la balise tr(). Exemple : tr(&#171;&#160;bonjour&#160;&#187;). En QML, le mot clé &#171;&#160;tr&#160;&#187; a été remplacé par &#171;&#160;qsTr&#171;&#160;. Exemple : qsTr(&#171;&#160;bonjour&#160;&#187;). Le mot clé « qsTr » peut être remplacé d’après la documentation par &#171;&#160;qsTranslate&#171;&#160;, &#171;&#160;QT_TR_NOOP&#160;&#187; et [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le but de ce billet est de tester l’internationalisation des applications QML.</p>
<p>Je m’appuie sur la documentation Qt « QML Internationalization » disponible sur ce lien http://doc.qt.nokia.com/4.7-snapshot/qdeclarativei18n.html.</p>
<p><b>Mot clés :</b></p>
<p>L’internationalisation d’une application classique Qt passe par l’utilisation de la balise tr().<br />
Exemple : tr(&laquo;&nbsp;bonjour&nbsp;&raquo;).</p>
<p>En QML, le mot clé &laquo;&nbsp;<b>tr</b>&nbsp;&raquo; a été remplacé par &laquo;&nbsp;<b>qsTr</b>&laquo;&nbsp;.<br />
Exemple : qsTr(&laquo;&nbsp;bonjour&nbsp;&raquo;).</p>
<p>Le mot clé « qsTr » peut être remplacé d’après la documentation par &laquo;&nbsp;<b>qsTranslate</b>&laquo;&nbsp;,  &laquo;&nbsp;<b>QT_TR_NOOP</b>&nbsp;&raquo; et &laquo;&nbsp;<b>QT_TRANSLATE_NOOP</b>&laquo;&nbsp;.</p>
<p>Dans le code C++, j’utiliserai toujours le mot clé « tr » et dans mes fichiers QML, j’utiliserai le mot clef &laquo;&nbsp;qsTr&nbsp;&raquo;.</p>
<p><span id="more-3"></span></p>
<p><b>Tests :</b><br />
Je crée un projet de type QML Application.</p>
<p>Le fichier QML généré est le suivant.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">import Qt 4.7 <br />
Rectangle { <br />
&nbsp; &nbsp; width: 200 <br />
&nbsp; &nbsp; height: 200 <br />
&nbsp; &nbsp; Text { <br />
&nbsp; &nbsp; &nbsp; &nbsp; x: 66 <br />
&nbsp; &nbsp; &nbsp; &nbsp; y: 93 <br />
&nbsp; &nbsp; &nbsp; &nbsp; text: &quot;Hello World&quot; <br />
&nbsp; &nbsp; } <br />
}</div></div>
<p>Je modifie la chaîne HelloWorld  par <b>qsTr</b>(&laquo;&nbsp;Bonjour&nbsp;&raquo;).</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">import Qt 4.7 <br />
Rectangle { <br />
&nbsp; &nbsp; width: 200 <br />
&nbsp; &nbsp; height: 200 <br />
&nbsp; &nbsp; Text { <br />
&nbsp; &nbsp; &nbsp; &nbsp; x: 66 <br />
&nbsp; &nbsp; &nbsp; &nbsp; y: 93 <br />
&nbsp; &nbsp; &nbsp; &nbsp; text: qsTr(&quot;Bonjour&quot;) <br />
&nbsp; &nbsp; } <br />
}</div></div>
<p>Ce qui donne ceci en mode design :<br />
<img src="http://blog.developpez.com/media/design.png" width="208" height="245" alt="" /></p>
<p>Et cela en exécution:<br />
<img src="http://blog.developpez.com/media/execu.png" width="208" height="245" alt="" /></p>
<p>Interrogation :</p>
<p>Je n’ai pas traduit mon application mais j’ai quand même la chaîne « Bonjour » affichée.<br />
Pourquoi ?</p>
<p>Tout simplement car le module de traduction de Qt affiche par défaut le texte non traduit s’il ne trouve pas de traduction.</p>
<p>Traduction de l’application QML:</p>
<p>La traduction de l’application fonctionne grâce à plusieurs logiciels : lupdate.exe, lrelease.exe et linguist.exe</p>
<ul>
<li>lupdate sert à générer un fichier xml d’extension « .ts » contenant les traductions de plusieurs fichiers QML.<br />
Exemple : lupdate fic1.qml fic2.qml –ts trad.ts</li>
<li>lrelease sert à compiler le fichier ts en un fichier binaire d’extension « *.qm »<br />
Exemple : lrelease trad.ts</li>
<li>linguist est une application graphique d’aide à la traduction.</li>
</ul>
<p>Tests :</p>
<p>J’applique la traduction au projet ci-dessus :</p>
<p>Etape 1 : J’ouvre une ligne de commande dos et je me place dans le répertoire de mon application</p>
<p>Etape 2 : Je génère le fichier QtTraduction.ts<br />
<img src="http://blog.developpez.com/media/lupdate.png" width="667" height="179" alt="" /></p>
<p>Le fichier ressemble à ceci :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; <br />
&lt;!DOCTYPE TS&gt; <br />
&lt;TS version=&quot;2.0&quot;&gt; <br />
&lt;context&gt; <br />
&nbsp; &nbsp; &lt;name&gt;QtTraduction&lt;/name&gt; <br />
&nbsp; &nbsp; &lt;message&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;location filename=&quot;QtTraduction.qml&quot; line=&quot;9&quot;/&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;source&gt;Bonjour&lt;/source&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;translation type=&quot;unfinished&quot;&gt;&lt;/translation&gt; <br />
&nbsp; &nbsp; &lt;/message&gt; <br />
&lt;/context&gt; <br />
&lt;/TS&gt;</div></div>
<p>Etape 3 : Qt linguist</p>
<p>Je lance la commande : liguist QmlTraduction.ts et je choisi la langue cible de ma traduction.<br />
<img src="http://blog.developpez.com/media/choixTrad.png" width="424" height="290" alt="" /></p>
<p>Ici je renseigne la traduction française par une autre traduction française pour l’exemple.<br />
<img src="http://blog.developpez.com/media/linguist.png" width="747" height="645" alt="" /></p>
<p>Ensuite je valide la traduction par le bouton entouré sur l’image.<br />
<img src="http://blog.developpez.com/media/linguistValid.png" width="747" height="645" alt="" /></p>
<p>J’enregistre et je quitte l’application.</p>
<p>Dès lors, le fichier QmlTraduction est complété par la traduction.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; <br />
&lt;!DOCTYPE TS&gt; <br />
&lt;TS version=&quot;2.0&quot; language=&quot;fr_FR&quot; sourcelanguage=&quot;fr_FR&quot;&gt; <br />
&lt;context&gt; <br />
&nbsp; &nbsp; &lt;name&gt;QtTraduction&lt;/name&gt; <br />
&nbsp; &nbsp; &lt;message&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;location filename=&quot;QtTraduction.qml&quot; line=&quot;9&quot;/&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;source&gt;Bonjour&lt;/source&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;translation&gt;Salut&lt;/translation&gt; <br />
&nbsp; &nbsp; &lt;/message&gt; <br />
&lt;/context&gt; <br />
&lt;/TS&gt;</div></div>
<p>Etape 4 : Génération du fichier de traduction compilé</p>
<p>Je lance la commande : lrelease QtTraduction et j’obtiens un fichier QtTraduction.qm.<br />
<img src="http://blog.developpez.com/media/qm.png" width="1089" height="87" alt="" /></p>
<p>Etape5 : Lancement de l’application traduite.<br />
Pour appliquer la traduction via qmlviewer, il faut préciser les fichiers de traduction via la commande :<br />
Qmlviewer –translation QtTraduction.qm QtTraduction.qml<br />
<img src="http://blog.developpez.com/media/loadTrad.png" width="664" height="420" alt="" /></p>
<p>Voilà, je n’ai plus qu’à appliquer ce principe pour mes traductions d’applications QML.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
