Mono és Gtk áttekintés

Címkék

Nem olyan régen rászántam egy napomat és megismerkedtem a .NET csodáival, a C# nyelv rejtelmeivel, ezért szeretném megosztani a tapasztalataimat. Áttekintő jellegű leírást magyar nyelven sajnálatos módon nem találtam, pedig már nem olyan fiatal a terület.

Ha jól emlékszem 4 évvel ezelőtt kaptam egy C# könyvet. Konkrétan a C# mesteri szinten 21 nap alatt. El is kezdtem olvasni, viszont minden oldalon szerepelt az a mondat, hogy: Ez a funkció jelenleg csak a Microsoft .NET megvalósításban érhető el. Mivel már akkor is Linux-ot használtam desktopra, így gyorsan kedvemet szegte. Talán még egy HelloWorld-ot kipróbáltam az 1.0 alatti valamelyik béta Mono-val, viszont gyorsan halottnak könyveltem el a dolgok a Javaval szemben.

Jelenleg a C# nyelv erős szabványosítása miatt, valamit az erős háttérnek, továbbá a két párhuzamos implementációnak köszönhetően, úgy gondolom megállja a helyét. A tervezés és a megvalósítás utolérte, s talán mostanra le is előzte a Java lehetőségeit. Talán még a beágyazott rendszereken, és a mobil készülékeken láthatunk érdekes dolgokat a jövőben.

Feladatnak egy GPS Data logger meghajtóprogramjának megírását választottam. Az eszköz USB-re csatlakozik, egy soros átalakító van benne, ami PL2303-ként jelenik meg a rendszerben. Ezek után erre tudunk rácsatlakozni, és kommunikálni, letölteni a rögzített adatokat.

A döntésem azért a .NET-re esett, mivel Javaban már megtanultam régebben programozni, valamint ott csak külső class segítségével lehet elérni a soros portot (RxTx). A .NET viszont 2.0-s megjelenése óta támogatja az IO Port kezelést, így könnyedén kommunikálhatunk soros eszközeinkkel platformfüggetlenül. (Sportszerű nehezítés, hogy hiába érhető el driver Mac OS X alá, a Mono jelenlegi verziójában nem képest azt elérhető soros portként kilistázni...)

1. WinForms és Gtk#

Mivel először WinForms-szal próbálkoztam meg összerakni az alkalmazás kezelői felületét, rá kellett ébrednem, hogy bizony ennek a megvalósítás 1.9-es (2.0 beta) Mono változatban még közel sem teljes. A fejlesztést Mac OS X (Tiger) operációs rendszeren végeztem, ahol szerencsére már elkészült a natív GTK port, így már mindhárom főbb platformon lehet GTK#-ot használó alkalmazások futtatni. A döntés egyetlen hátránya, hogy a majdani kliens számítógépen nem elég a Microsoft .NET Framework telepítése (Windows esetén), hanem Mono-t igényel.

Fordításhoz szükséges beállítások:


   export PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/Versions/1.9/lib/pkgconfig/

Esetemben így nézett ki. Ez arra a célra szolgál, hogy a rendszer megtalálja a gtk-sharp-2.0.pc fájlt. Más rendszereken ilyen hiba esetén célszerű locate segítségével felderíteni, hol található a fájl, majd exportálni a PATH-ben a könyvtárat. Tehát:


   $ locate gtk-sharp-2.0.pc
   /Library/Frameworks/Mono.framework/Versions/1.9/lib/pkgconfig/gtk-sharp-2.0.pc

Ha már így rendelkezésünkre áll, akkor a fordításánál pkg paraméter segítségével használhatjuk is.


   $ gmcs -pkg:gtk-sharp-2.0 [gtk-t használó forrás fájl.cs]


Megjegyzés: mcs segítségével 1.1-es .NET platformra, még gmcs segítségével 2.0-sra tudunk fordítani

2. Az első GTK# alkalmazásunk

Mivel MonoDevelep Mac OS X-es változata nem támogatja a GTK# fejlesztést, valamint maga az IDE eszköz is hiányosnak és lassúnak tűnt, megmaradtam a Vim használatánál. Az XCode plugint szintén lustaság okán nem állítottam be, amúgysem használom, hiába hallottam róla jókat.

A fejlesztést továbbiakban két terminálban folytatjuk. Az egyikben a Vim, vagy kedvenc szerkesztőnk állandó jelleggel mutatja a forráskódot. A másikban a fent említett PATH beállítva, az ismertetett módon fordítjuk és futtatjuk az alkalmazást. Lelkesebbek erre írhatnak scriptet is...

Az első programunk kódja a következő lesz:


   $ cat FirstGtkApp.cs
 
   using System;
   using Gtk; 

   public class GtkHelloWorld { 

     GtkHelloWorld() {
        Application.Init(); 

        Window myWin = new Window("My first GTK# Application!");
        myWin.DeleteEvent += new DeleteEventHandler (OnWinDelete);
        myWin.Resize(200,200);
      
        Label myLabel = new Label();
        myLabel.Text = "Hello World!!!!";
        
        myWin.Add(myLabel);

        myWin.ShowAll(); 

        Application.Run();
     }

     public static void Main() { 
        new GtkHelloWorld();
     }

     private void OnWinDelete (object o, DeleteEventArgs args) { 
        Application.Quit();
     }

  }

Először két névteret kell használatba vennünk a grafikus alkalmazás elkészítéséhez. Ezek a Gtk, és System namespace. Első felelős a nekünk szükséges elemek bekerüléséért.

Az alkalmazás Main függvényében példányosítjuk az osztályunkat. Ez eredményezi a konstruktor lefutását, amiben ténylegesen megvalósítjuk a megjelenítést. Először az alkamazást inicializáljuk az Application.Init(); függvényhívással. Későbbiekben ehhez hasonlóan az Application.Run(); segítségével fogjuk futásra bírni.

Előtte azonban még létre kell hoznunk egy ablakot, amire rajzolni szeretnénk. Ez a Window osztály egy példányának létrehozásávál történik. Konstruktorába az alkalmazás neve kerül. Ezt a későbbiek során Window.Title publikus string változó módosításával tudjuk átállítani. A Window.DeleteEvent-hez rendelünk egy eseménykezelő függvényt, ami azért fog felelni, ha bezárjuk az ablakot, akkor az alkalmazás is lépjen, és visszakapjuk a konzolt.

Következő lépésben a Label osztály segítségével egy cimkét hozunk létre. Itt is használhatjuk a konstruktort a szöveg megadására, vagy az itt alkalmazott módon tudjuk módosítani.

Ezek után már csak rá kell helyeznünk a Window osztály Add() függvényével a Widget-ünket az ablakra. Majd beállítani, hogy minden megjelenjen a képernyőn. Az elemek láthatóságát külön is lehet állítani. Erre az egyes osztályok Show() függvénye szolgál. Jól jön akkor, ha bizonyos funkciók csak események hatására lesznek elérhetőek.

Most már csak fordítanunk és futtatnunk kell az alkalmazást.


   $ gmcs -pkg:gtk-sharp-2.0 FirstGtkApp.cs
   $ mono FirstGtkApp.exe FirstGtkApp.exe

Megjegyzés: Azért nem a Main függvénybe került az egész kód, mert későbbiek során is hajlamosak lennénk ott hagyni, és bizonyos esetekben a static definíció miatt a fordító különféle warningokkal ajándékozna meg minket. Természetesen a helyes megoldás, hogy minden ablakot külön függvényben írunk le, és igény szerint hívjuk meg őket.

3. Tárolók

Ezeket az osztályokat használjuk a képernyőn megjeleníteni kívánt elemeink elrendezésére. Ugyanazt a célt szolgálják, mint Javaban a layout-ok. Az ablakokat gyakorlatilag területekre osztjuk fel, amikbe belepakoljuk a látványelemeket.

Az elérhető alap típusok listája (nem teljes):

  • Fixed: rögzített kinézet hozható vele létre, pixelre pontosan meg tudjuk adni, hogy mi hova kerüljön
  • VBox: vertikális felosztása az adott területnek, amit hozzáadunk, az automatikusan függőleges oszlopba rendeződik
  • HBox: előzőhöz hasonlóan, csak horizontálisan történik az elhelyezés
  • Table: az általunk definált méretű táblazatot hozhatunk létre, aminek a rácspontjaira feszíthetjük ki az elemeinket
  • Frame: elemek keretbe foglalására szolgáló tároló
  • ScrolledWindow: amit belehelyezünk, az scrollozhatóvá válik, ha nem fér ki a képernyőre (pl.: TextView)

A tárolók méretét a Widget osztályból örökölt SetSizeRequest(int x, int y) metódus segítségével állíthatjuk be.

Az ablakhoz történő hozzáadásuk ugyanúgy történik, ahogy a többi elemé is, a Window.Add() függvényben paraméterként megadva.

Megjegyzés: Véleményem szerint érdemes először egy VBox tárolót elhelyezni a képernyőn. Ebbe helyezni a menu sort, az ablak középső részét, valamint a státus sort. Ezek után pedig a középső rész a megfelelő rétegekkel igény szerint feltölteni.

3.1 Fixed tároló

A tárolónak van paraméter nélküli konstruktora, legegyszerűbb azt használni a létrehozásnál.


   Button testButton = new Button("Teszt");

   Fixed fixArea = new Fixed();
   fixArea.SetSizeRequest(100,100);

   fixArea.Put(testButton,10,10);

Ezzel létrehoztunk egy 100x100 négyzetet, aminek a (10,10) pontjába helyeztük a Teszt feliratú gombunkat. Az elemek bal felső sarka kerül mindig az általunk megadott koordinátára.

3.2 VBox és HBox tároló

A következő példában három gombot fogunk létrehozni. Minden a Teszt felirat szerepel sorszámozva. Legfelül lesz az 1-es számú, és alatta a második sorban egymás mellett a 2-es és 3-as számú.


   Button testButton1 = new Button("Teszt1");
   Button testButton2 = new Button("Teszt2");
   Button testButton3 = new Button("Teszt3");

   VBox vbox = new VBox(false, 1);
   HBox hbox = new HBox(false, 1);

   hbox.Add(testButton2);
   hbox.Add(testButton3);
   vbox.Add(testButton1);
   vbox.Add(hbox);

Láthatóan mindkét tároló konstruktora két paramétert vár. Az első egy logikai változó, ami azt adja meg, hogy a rendszer kikényszerítse-e a benne elhelyezett elemektől, hogy egyenlő méretekkel rendelkezzenek. A második paraméterben pedig az elemeket elválasztó terület nagyságát adhatjuk meg egy integer segítségével.

3.3 Table tároló


   Button testButton1 = new Button("Teszt1");
   Button testButton2 = new Button("Teszt2");
   Button testButton3 = new Button("Teszt3");
   Button testButton4 = new Button("Teszt4");

   Table newTable = new Table(2,2,true)

   newTable.Attach(testButton1, 0, 1, 0, 1);
   newTable.Attach(testButton2, 1, 2, 0, 1);
   newTable.Attach(testButton3, 0, 1, 1, 2);
   newTable.Attach(testButton4, 1, 2, 1, 2);

A létrehozáshoz meg kell adnunk hány sort és oszlopot szeretnénk a táblázatban. A harmadik paraméter itt is a homogén méretezés kikényszerítését jelenti.

Ezek után a meglévő elemeinket csatolni kell a táblázathoz az Attach függvény segítségével. Első paraméterében várja a Widget osztályból öröklődött elemet, amit hozzá akarunk adni. A tovább négy paraméterben a helyet, hogy hova szeretnénk rakni. Az első két koordináta adja meg, hogy melyik két oszlop között tart az elem. A második két koordináta, hogy melyik két sor között. A táblázat bal felső saroktól számozódik, 0-tól kezdődően. Tehát a példában szereplő 2x2 táblázat bal felső celláját láthatóan a (0,1,0,1) paraméter négyessel tudjuk kijelölni.

3.4 Frame tároló


   Button testButton = new Button("Teszt");

   Frame labeledFrame = new Frame("Keret:");

   labeledFrame.Add(testButton);

A példa nem túl életszerű, viszont látható, hogy a gombunk körül egy keret helyezkedik el, aminek a bal felső részébe található a címke. Az osztálynak van paraméter nélküli konstruktora is. Ekkor a Frame.Label publikus string változón keresztül tudjuk a címkét megváltoztatni.

3.5 ScrolledWindow tároló

Hasonlóan a Frame-hez, létrehozás után egyszűen hozzá kell adni a kívánt elem(ek)et. A konstruktor nem vár paramétereket, címkével nem rendelkezik. A TextView-val együtt szemléltetésre kerül a későbbiek folyamán.

4. Elemek

Néhány egyszerűbb elem, amit könnyedén a képernyőre lehet helyezni, és még hasznuk is van.

  • Label: a példában is szereplő címke osztály
  • Button: egyszerű nyomógomb
  • ComboBox: legördülő lista, elődje az OptionMenu, ám az elavultá vált, ez használandó helyette
  • TextView: szöveg megjelenítésre alkalmas mező, akár szerkeszthető is, szükséges mellé a TextBuffer osztály
  • MessageBox: üzenet ablak megjelenítése
  • RadioButton: ismert választó gomb
  • CheckButton: ismert jelölő négyzet
  • VSeparator: függőleges vonal elválasztásra
  • HSeparator: ugyanaz vízszintesen
  • StatusBar: státusz sor, amit az ablak alján használunk
  • Tree: listázott megjelenítés

4.1 TextView elem

Összetettebb példának hozzunk létre a képernyőn egy olyan mezőt, ahova az alkalmazás a továbbiakban loggolni fogja a tevékenységeit. Ez a mező legyen görgethető, és kijelölhető, az esetleges szöveg másoláshoz, viszont módosítani ne lehessen.


   TextView view;
   TextBuffer buffer;
   Frame logFrame;
   ScrolledWindow logWindow;

   logFrame             = new Frame();
   logFrame.Label       = "Log:";
   view                 = new Gtk.TextView ();
   view.Editable        = false;
   view.CursorVisible   = true;
   buffer               = view.Buffer;
   buffer.Text          = ""; 
   logWindow            = new ScrolledWindow();
   logWindow.SetSizeRequest(480,200);     

   logWindow.Add(view);
   logFrame.Add(logWindow);

A megvalósításhoz a TextView elemet fogjuk használni. Ebben az elemben egy TextBuffer típusú változó tartalmát fogjuk megjeleníteni, amit működés közben folyamatosan írunk, jelen esetben hozzáfűzünk.

A naplózást tartalmazó mezőt egy Framebe ágyazzuk, amit felcimkézünk a "Log:" felirattal. Ezek után létrehozzuk a TextView-t és beállítjuk a kívánt paramétereket. Következőkben a TextBuffer változót összerendeljük a TextView osztály azonos típusú publikus változójával. Ezek után létrehozzuk a ScrolledWindow típusú változót, amibe bele fogjuk helyezni ezt az elemet, és ezt az ablakot ágyazzuk a Framebe.

4.2 ComboBox elem

Ezt az elemet csak azért emeltem ki, mivel talán kellően gyakran használt, és talán másik is belefutnának abba a hibába, hogy először az OptionMenu osztályt akarják használni. Aztán csodálkoznak a fordító által jelzett Warningokon, miszerint az elem elavult.

A használata egyszerű. Létre hozás során inicializálni kell a Text elemét, és ahhoz hozzá fűzni sorban a kívánt lista elemeket. Alapvetően a leghosszabb lista elem méretét veszi fel, ám véleményem szerint érdemes előre beállítani a már ismertett módon.

   
   ComboBox combo;

   combo = ComboBox.NewText();

   for (int i = 0; i < 5; i ++)
      combo.AppendText ("item " + i);

4.3 StatusBar elem

A státusz sor hozzáadás hasonlóan történik az összes többi elem, egyszűen példányosítani kell, és utána hozzáadni a megfelelő Object leszármazott elemhez. Az érdekessége, hogy szöveget megjeleníteni rajta hasonlóan lehet, mint egy verem. Két hasznos függvénye van, a Push() és Pop(). Az elsővel látható módon írhatunk rá, a másodikkal eltávolíthatjuk azt. A stackre való lenyomásnál egy sorszámot is rendelhetünk az üzenethez, ez lesz első paraméter, míg a szöveg a második. A Pop(int id) függvénnyel, mert a kívánt azonosítójú string-et távolítjuk el. A példában még egy tulajdonságát állítottuk be a StatusBarnak, méghozzá azt, hogy megjelenítse az átméretező sarkot, vagy sem. Tapasztalataim szerint ez Windows alatt sikeresen működik is, míg Mac OS X alatt figyelmen kívül hagyja.


   
   Statusbar sb;

   sb = new Statusbar();
   sb.HasResizeGrip = false;
   
   sb.Push (1, "Welcome!");

4.4 Tree elem

Erről az elemről a GtkSharp hivatalos oldalán is található egy kellően részletes leírás. Én itt ezt egy kicsit leegyszerűsétettem. Demonstrálás szempontjából megfelelő, viszont a Tree erejét nem fejezi ki kellően, így érdemes elolvasni.

A következőkben létrehozunk egy elemet, amiben található egy Items cimkével rendelkező oszlop, és abban öt sort, amiben az itemek vannak felsorolva.

Először létrehozzuk magát a TreeView-t, amibe pakoljuk az elemeket. Ilyen az oszlop, amiből most csak egyet hozunk létre. Szükség van még két további változóra. Az egyik felel azért, hogy a listában látszódjanak az elemek, míg a másik magát a listát képezi. A listánál meg kell adnunk, hogy milyen típusú és mennyi elemet tárolunk benne, ezért a konstruktora változó hosszúságú paramétersort igényel.

Ezek után beállítjuk a tároló oszlopot. Adunk neki nevet, illetve magát a fejléc mezőt helyezzük el, és megmondjuk neki, hogy alatta text típusú elemek fognak sorakozni. Ezek után a TreeView elem Model objektumának megadjuk, hogy az általunk létrehozott ListStoret használja. Innentől már csak az itemListStore változót kell feltölteni, amit a for ciklus szemléltet.

   
   TreeView tree                   = new TreeView();
   TreeViewColumn itemColumn       = new TreeViewColumn();
   CellRendererText itemNameCell   = new CellRendererText ();
   ListStore itemListStore         = new ListStore(typeof (string));

   itemColumn.Title                = "Items";
   itemColumn.PackStart (itemNameCell, true);
   itemColumn.AddAttribute (itemNameCell, "text", 0);
   tree.AppendColumn(itemColumn);                
   tree.Model = itemListStore;

   for (int i = 0; i < 5; i ++)
       portListStore.AppendValues("item " + i);

5. Eseménykezelés

Miután már szépen tele tudjuk rajzolni a képernyőt, ideje megismerkedni annak a módjával, hogyan is tudjuk életrekelteni az alkalmazásunkat.

Ennek a legjobb módja, hogy bizonyos elemekhez olyan függvényeket rendelünk, ami a rendszer által detektált eseményeknél lefutnak. Ilyen lehet például, egy gomb megnyomása, ablak átméretezése, TextBox szerkesztése, menu elem kiválasztása...

A megvalósítás menete, hogy a Widget eseményéhez hozzáadunk, egy új eseménykezelő osztályt.


   helloButton.Clicked += new EventHandler(helloButton_Clicked);

   private void helloButton_Clicked(object o, EventArgs args) {
      Console.WriteLine("Kattintás...");
   }

A gomb Clicked eseményez adtuk hozzá az általunk megírt helloButton_Clicked függvényt. Ez a függvény private, mivel nem szeretnénk, hogy az osztályunkon kívül bármi is meghívja, és void, mivel nincs visszatérési értke. A rendszer a függvénynek átadja, hogy melyik objektum hívta meg. Itt például, ha kattintás esetén át szeretnénk írni a gomb szövegét, akkor a Label módosítása előtt az objektumot vissza kell kasztolni Button típusúra. Az EventArgs osztály tárol az eseménykezelő számára használható adatokat. A példakódban kattintás esetén csak egy sort írunk ki a konzolba.

A Button osztály eseményei:

  • Activated: ha a gomb aktiválva lett
  • Clicked: ha rákattintunk
  • Entered: ha az egérmutató a gomb területére ér
  • Left: ha az egérmutató a gomb területét elhagyja
  • Pressed: ha a gombot lenyomomják
  • Released: ha a gombot felengedik

6. Néhány javaslat

Mint programozás során mindig, itt is érdemes követni egy struktúrális logikát. Aki évek óta foglalkozik ezzel a területtel, annak már biztosan megtörtént. Többieknek adnék néhány szerény tanácsot.

A C hagyományok szerint még mindig érdemes először a változókat definiálni a programkód elején, hogy lássuk, miket is akarunk felhasználni. Így kevesebb a valószínűsége, hogy valami feleslegeset is létrehozunk, és ott marad a kódban.

A következő részben érdemes az elemek példányosítását megcsinálni, és beállítani a megfelelő tulajdonságaikat, amiket később látni szeretnénk.

Harmadik lépésként építsük fel a konténerek elrendezését egymásban. Ha előállítottuk a kívánt struktúrát, akkor adjuk hozzá az elemeket a megfelelő, előre elképzelt helyekez. A tervezés segít elkerülni az elkavarodást a helyek között.

Végül adjuk hozzá az ablakhoz a konténereket, és jelenítsük meg a felhasználó felé.

Hozzászólások

Szakmailag nem tudtam ellenőrizni, mert lövésem sincs a témához, de jó látni, hogy valaki tudja ismeri a HTML-t és vágja, hogy egy cikknek hogyan kell kinéznie. Cikkbeküldők előtt állhat példaként. :)

--
trey @ gépház

Vaov, nagyon jo cikk. Egesz meghoztad a kedvem a C#hoz, pedig en nagyon ellene voltam.

Nem mintha valaha is programoztam volna .Net/C#-al, de én egy másik "struktúrális logikát" preferálok a napi munkámban ill. szabadidőmben programozva (Java, C++).

Én minden változót a (első) használatához leközelebbi helyen és scope-ban vezetek be, inicializálok/példányosítok és paraméterezek fel (ha lehetséges). Amire később/máshol is szükségem van, az úgyis adatmezőként végzi egy osztályban, vagy más helyen, és arról ott kell gondoskodni. A mai fordítók de fejlesztőeszközök is tudnak figyelmeztetni a nem használt vagy használat előtt nem inicializált változókra.

Miért jó az, hogy egy programot c# -ban írnak? Főleg azokra a programokra gondolok, amit soha nem is szántak arra, hogy vindózon kívül máson is fusson. Pl. Ati controll center.

A Caesar 4, Microsoft Encarta (2005 utániak) nem indul el .net nélkül. Valamire csak kell neki. Nem tudom, hogy egy játékprogramba minek.

Remélem a managelt memóriakezelés jobb, mint java-ban. JEdit-et használok text editornak. 10 rövidke állomány van megnyitva jelenleg. Saját bevallása szerint 50MB-ot foglal (java heap memory). :(

Fapadot kedvelő C/ASM programozóként nekem pl vallási problémáim vannak a ++-szal. Valószínűleg nagyon hasonló, mint amilyen problémája a ++-osoknak van a #-pal. :)

Múltkor beesett egy projekt, soros porton adatot csorgató RFID olvasót kellett mysql-es dolgozói adatbázisból ellenőrizni, beengedni, naplózni. Mondom, tanuljunk valami újat, a C# ránézésre elég ellenszenves, jó lesz vele szívni egy hetet. Aztán nagyjából három órával és 20 sor kóddal később működött az egész. Meggyőzött. (Fő munkaeszközként maradtam a C-nél, de a bemutatkozás kellemes volt.)

(Ehhez még hozzájön, hogy a marketingje szerint ez a C/C++ következő evolúciós fokozata és mást már csak nyugdíjas hobbiprogramozók használnak. Szóval...)

Szerintem sokkal tisztabb a .Net API-ja mint az alap windows-os ami meg Win3.1-es maradvanyokat is tartalmaz. Plusz nem kell figyelni a memoria kezelesre, pointerekre stb, ami nagy konyebbseg tud lenni. Az igazsaghoz hozzatartozik, hogy nem sokat programoztam C++-ban, de amikor .Net utan meglattam a win API-jat, hat a hanyinger kerulgetett.

Egyebkent nekem egyedul a mono, gtk#-al kapcsolatban csak az volt bajom, hogy nem teljes a dokumentacio. Egy TreeView pl. szerintem kicsit tul van bonyolitva, mire minden CellRenderer-t es hasonlot beallitottam eleg szepen megszenvedtem. E

Ehhez muszáj csatlakoznom. Hihetetlenül meggondolatlan dolog volt egy olyan rendszerközeli eszköz elkészítése .NET -el, mint az ATI CCC.

Ráadásul a megvalósítása is egy határ sz*r: nekem egyszerűen nem hajlandó elindulni. (Windows Update-n keresztül rendszeresen frissítem a rendszert és egyébként _minden_ más kifogástalanul működik). Állítólag csak az egyik verziójú .NET framework telepítettsége esetén (vagy csak a három: 1.1, 2.0, 3.5 valamilyen kombinációjában) működik. Nekem nem hajlandó elindulni. Olvastam troubleshooting listákat hiszen rengeteg ember tapasztalja ezt, minden feltétel megfelelő, mégsem.

A főiskolán egyébként C# nyelven kezdjük (és folytatjuk) a programozást. Első félévben objektumorientált programozás bevezetése folyik C#-ban, másodikban pedig Vizuális/eseményvezérelt programozás (kezdetben konzolos "játékok", később Windows Forms-os különféle célú egyszerűbb progik), és Programozási paradigmák és technikák laboron használjuk (interfészek, property-k, objektumok kezelése, függvények, stb), általában mindenki elégedettségére.

Hozzáteszem legutóbbi laboron a Visual C# Express 2005 valamilyen hibát észlelt egy olyan sorban, ami ÜRES volt, így megtagadta a fordítást. Mindenféle trükközésünk ellenére, egy bizonyos tartományban ami vagy üres volt, vagy működő kód volt rajta, (16-18. sor környéke) minden esetben hibával elszállt. Bug, bár a félév korábbi laborjain rendben teljesített.

http://gyuszk.homelinux.org

-- There is never time to do it right, but always time to do it over.

"Ehhez muszáj csatlakoznom. Hihetetlenül meggondolatlan dolog volt egy olyan rendszerközeli eszköz elkészítése .NET -el, mint az ATI CCC."

Az ATI CCC aztán nagyon rendszerközeli. Maximum abban merül ki a rendszerközelisége, hogy maximum a WinAPI -n keresztül matat mélyebre. A driver attól még natív kód.

Ati CCC .Net-be költözése szerintem elég logikus dolog volt annak idején.
Arról ugyanis megfeletkeztetek, hogy ez a költöztetés lehetővé teszi a CCC számára, hogy XP és Vista mint 32 mint 64 bites változatain tudjon futni. Ezzel egy csomó időt spóroltak az Atisok (nem kellet Xp-32, Xp-64, Vista-32 és Vista-64 verziókat külön-külön írni). Valószínűleg tartom, hogy ezért tudtak annó Vistára jóval az NV előtt jól működő driverrel kijönni. (Ezzel egy jelentős kódbázist rendszer függetlenné tehettek, és nagyobb erőkkel lehetett a mindenképp rendszerfüggő driverekre öszpontosítani.)
Egyébként nekem magamnak is az a véleményem, hogy ha nem túl nagy befektetéssel akarunk Xp és Vista, illetve 32 és 64 bites platformokat egyszerre támogatni, akkor jelenleg a DotNet az egyetlen normálisan járható út.

Zavard össze a világot: mosolyogj hétfőn.

Hm..köszi neked és saxusnak a kiigazítást.

Egyébként lehet hogy jó ötlet volt, mégis igen-igen problémásra sikerült megvalósítani. Nem véletlenül használnak sokan Omega-drivert (optimalizált, tweakelt Catalyst), amelyről lecsutkázták a .NET -es CCC-t, és a klasszikust tették vissza (és bővítették ki).

http://gyuszk.homelinux.org

-- There is never time to do it right, but always time to do it over.

HUPWikibe postoltad?

megj.: Epp most szorakozgatok a QT-vel C++ alatt (mar itt is atlatom), viszont Java nyelven QT-t programozni maga a mennyorszag (qtjambi). Namost, arra gondoltam viszont, hogy az Ubuntu+Gnome hatalmas eloretorese miatt jo lenne inkabb valami GTK-sat programmirozni - a GTK+C nagyonnagyon nem jon be (pedig ahol lehet a C-t preferalom), a Java+swt kodja meg megintcsak csunya a Qt-hez kepest.

Ez viszont ujra bejon. Qt-s egyszeruseggel (es atlathatoan) lehet felepiteni a feluleteket, es tobbplatformos. Hmm.... :)

Mi a helyzet a teljesitmennyel? Hallottam hireket, miszerint lassabb, mint a Java, stb. Par milliszekundumnyi szamitasi teljesitmeny nem zavarna, inkabb a GUI responsiveness-e erdekel. Hm?

jó kis leírás. köszi

Szerintem a sebességgel nincsen probléma, ha a Java-val hasonlítjuk össze.

Hali, jo kis kedvcsinalo leiras!
Amugy sajna az a sor, hogy winen is mono kell, h fusson a cucc, eleg kiabrandito.
A gui cuccok miatt tenyleg jo lenne a sharp, de ha kell plusz cuccokat telepiteni, hogy ugyanaz a kod ugyanugy fusson, akkor egy java-t is fel lehet mar csapni, s ott tuti ugy mukodik minden ahogy a masik platformon is.

hat ja az a cel h kompatibilis legyen, de meg akik nagy terjesztoi voltak az egyetemen, azok is csendben megsugtak, h a gui, hat bizony az nem nagyon fog futni mashol:) persze azota gyanitom probaltak fejleszteni a dolgon, de meg el-elcsipek ilyen velemenyeket ittott. Lehet h nem veletlenul tolja az ms a silverlight-ot...ha mar platform fuggetlen gui.

igazabol a gtkt elkene felejteni ugy ahogy van :-)

a .net meg odaver.

bar feladat valogatja; en ugy vagyok most vele, hogy kliens oldali kodot .NET, szerver oldalit meg EE. mondjuk nem webprogramozo vagyok, ugyhogy nem pancsolok weboldalokat, de mondjuk webszervizeket itt tok kenyelmes hasznalni (foleg hogy van ORM); ASP.NET -ben nem tudom mennyire van erre lehetoseg, meg nem akartam sosem irni ott webszervizt.

Így van, a LINQ nem egy perzisztencia réteg, annál jóval több. :)
Keretrendszerbeli, nyelvbeli és fejlesztőeszközbeli támogatás arra, hogy tíz perc alatt megírd (legeneráld) a saját perzisztencia-réteged. Nem mellesleg teljesen elfedve a domain réteg elől, hogy ő most tulajdonképpen adatbázisba, XML-be, memóriabeli szerkezetbe, vagy tetszőleges, adatot stuktúrált módon tárolni képes akármibe dolgozik.

Természetesen a DML utasítások is támogatottak a DataContext osztály SubmitChanges() metódusán keresztül.
LINQ to SQL: Inserting data through Object Model
LINQ to SQL: Update data through Object Model

Ami miatt sok a félreértés a LINQ körül, az az, hogy elég homályos a terminológia. A LINQ-kel egy nagy csomó új nyelvi feature, fejleszőeszköz és egyéb tool támogatás, technológia jött be a .net-be. Ezekre hol gyűjtőnévként használják a LINQ-et, hol csak a új szintaktikát értik alatta, hol meg megint mást, mint én itt föntebb a DLINQ-et (ami kétségtelenül nem egészen helyes, de a hibrid mód topicban nem akartam túlfeszíteni a húrt).

Hát, jó a kérdés. Fejlesztői szemszögből talán az, hogy a (D)LINQ egy alapvetően más programozói modell. Sokkal jobban idomul az OOP-hez, így valószínű a legtöbb fejlesztőnek kényelmesebb használni.
Technikai szempontból nem tudom, mert a típusos dataset alját abszolút nem ismerem (a tetejét se nagyon), valószínű vannak nálam kompetensebbek a kérdés megválaszolására. :)

Hmm, felkerül a megtanulandó dolgok listájára. :) Jelenleg a java szerepel előkelő helyen még ezen a listán, és ahogy a kommentek alapján olvasom, a kettőnek programozási szempontból sok köze van egymáshoz.

Tapasztaltabbaktól kérdezem, hogy ez a programnyelv mennyire alkalmas prociigényes matematikai prblémák megoldására? (Nem akarok indíg mindent 2*írni, mert grafikus felületet is kell produkálnom, és az win/lin esetén totál más)

Proci igényes matematikai prblémák megoldására szerintem a legjobb, ha a legalacsonyabb szinten programozod le. Szerintem nem is kellene az egész programot alacsony szintű programozási nyelven megírni, elég ha csak azt a programrész írod meg ami a matematikai számolásért felelős. Szerintem.

sly @ w3m.hu

C-ben szoktam írni (diffegyneletmegoldás meg egyebek asm-ben kicsit túl sok időt emésztenének fel, míg megírom jól. Addigra a C-kód rég végez mire megírom asmben, tény hogy gyorsabb, de rohadtul nem éri meg, max 20%-tot tapasztaltam eddig). Mert az eredmény cask 1-2 alkalmommal kell nem fut a pogram állandóan évekig.....

Nem tudom, mire gondolsz? Nyelvi támogatás annyi van, amennyi egy általános célú programnyelvtől elvárható: alapműveletek, a Math osztályon keresztül trigonometrikus, logaritmikus, kerekítési, stb függvények.
A sebesség témája: fordításkor IL kódot generál a fordító, ami futtatáskor on the fly lefordul natívra, onnantól az fut, így sebességben szintén kb. azt hozza, amit a többi általános célú nyelv.
Így első blikkre egy dolog lehet necces: a GC. Ha sok temporális objektumot csinálsz, amit aztán hamar eldobsz, akkor érdemes lehet olyan nyelvet választani, ahol te tudod kontrollálni a memória-felszabadítást.

Nem használtam, ezért írtam, hogy állítólag. Mivel rémlik, hogy valahol valaki nagyon szidta.

Erről a régebbi qt frontendről meg nem hallottam. Ettől függetlenül, mivel valószínűleg nagy szívás átírni wxWidgets-ről egy alkalmazást QT4-re, talán van valami oka az átállásnak.

> A QT-t nem ismerem, mert nem vagyok milliomos.

LOL. Ez kicsit demagog igy, nem gondolod? :)

Az osszes milliomos viszont ismeri. A golf- es yacht-klubok tulajdonkepp a trolltech hetvegi szorakoztatokozpontjai.

Szoval attol, hogy nem csinalhatsz vele nemcsak GPL-es appokat, meg lehet tanulmanyozni, sot eleg sok pelda talalhato hozza a neten, szoval - ha egy internetelerest, es a villanyszamlat ki tudod fizetni, akkor akar - ismerheted a QT-t.

Ha a MonoDevelop-al gui hegesztes nem ment, glade -vel is eleg egyszeru es nagyszeru dolgot lehet muvelni.
pl [Widget] -moge erdemes benezni :)

wow, nagyon jó cikk, köszönjük!
én 4 éve tolom a C# + .net világot magam előtt igaz webes projektekkel, a desktop-dolgokat csak windows service-k formájában ismerem (jó, összesakkoztam már pár gui alkalmazást is VS-ben), de a GTK cuccoktól mindig is féltem egy kicsit, egy kis projektnél C-ben már játszottam vele, de megőszültem tőle :D

Viszont most felnyitottad a szemem, amint időm engedi megnézem és megpróbálom ismét - én is OS X alatt szeretek dolgozni, hátha vissza tudok térni teljesen.... (bár a MonoDevelop még a webes fejlesztést khm. fogalmazzunk úgy nem nagyon támogatja [auto code-snipps, intelisence-mockup etc..])

~ubuntu, os x~

bár annyit még hozzátennék, hogy ha a nagy Gnome-evangélista szája íze szerint (Miguel) mennek a dolgok akkor én a következőt látom a linux-desktop jövőjének:

C# mint Gnome default language, GTK (Moonlight mint widgets) mint GUI, Cairo alapon... kihagytam valamit?:)

~ubuntu, os x~