Icoon voor je project

  • Default map icon er is een standaard icoon voor gambasmappen; een map gecobineerd met een blauwe garnaal: .icon.png; de naam begint met een punt en is daardoor onzichtbaar. In een eveneens “onzichtbaar” bestand .directory staat het icoon aangegegeven voor deze directory (in KDE):
    [Desktop Entry]
    Icon=./.icon.png

    Blijkbaar: Als er een icoon gekozen is in het project, wordt dit gecombineerd met een standaard map-icoon tot een nieuw waar beide in voorkomen.
  • Er is ook een standaard icoon voor een project; de blauwe garnaalkop.
  • Het icoon kan je kiezen bij menu project, properties; klik op de grote icoon-knop om het icoon te kiezen uit je bestanden.
  • Als je het project compileert vanuit de IDE maakt die een icoon op de desktop aan om het programma te starten; dit icoon wordt daarvoor gebruikt (anders standaard icoon).

Database opvraging met result set

Een sterk hulpmiddel voor het opvragen van gegevens uit een databank en verdere verwerking ervan is de “resultset”, de resultaatset van de opvraging. Een opvraging bestaat meestal uit een tekstlijn met een SQL query. Die kan op voorhand opgebouwd worden in een variabele.
Er wordt trouwens aangeraden om eerder de echte variabelen mee te geven als parameters.( zie Databank aanspreken..)

sRequest = "SELECT * FROM &1 LIMIT &2"
TRY myResult = db.Exec(sRequest, "test", "2000")

Met de resultset kan je dan hetvolgende:

  • Kijken hoeveel records of resultaatrijen er zijn:

    PRINT myResult.Count

  • bewegen met de pointer of index:

    Die begint te tellen bij 0 en kan gevolgd worden met:
    PRINT myResult.Index

    Naar een bepaalde rij:

    myResult.MoveTo(iRow)

    Naar een relatieve rij bewegen met de pointer: eerste, laatste, volgende, vorige

    myResult.MoveFirst()
    myResult.MoveLast()
    myResult.MoveNext()
    myResult.MovePrevious()

    Een veld uit het huidige record aanspreken:
    PRINT myResult!fld_name

    Omdat het een “enumerable” resultset is hoef je zelf niet te tellen, maar kan je FOR EACH gebruiken:

    FOR EACH myResult
    PRINT myResult!fld_id & " - " & myResult!fld_name
    NEXT

    (als de databank-tabel de velden fld_id en fld_name bevat )

  • De inhoud van een veld opvragen om in te vullen in bv een TableView:

    TableView1.Data.Text = myResult[sVeldnaam]

Extra interessant zijn de “subcollecties”: bv de beschikbare velden:

myResult.Fields[]

Die zijn “enumerable”: dwz te gebruiken met FOR EACH. Je moet wel een “tellervoorwerp” hebben; bv een veld.

DIM myField AS Field

FOR EACH myField in myResult.Fields
‘ …
NEXT

Voorbeeld:

PUBLIC SUB fillLsbxTableFieldsForEach()
'
' try to make a better fillListbox by using enumerated type
'  
  DIM iInd AS Integer
  DIM sTableAndFields AS String
  DIM hField AS Field
  DIM hTable AS Table
'  
  DEBUG "Database:" & lsbxDatabases.Current.Text
  WITH $hConDb
    .Name = lsbxDatabases.Current.Text
  END WITH 
  $hConDb.Close
  $hConDb.Open
  TRY $hRes = $hConDb.Exec("SHOW TABLES")
  IF ERROR 
    Message.Error(Error.Text, "ok")
  ELSE 
    DEBUG $hRes.Count
    $hRes.MoveFirst
    lsbxDbTables.Clear
    FOR EACH hTable IN $hConDb.Tables
    '[$hRes[Str($hRes.Fields[0].Name)]]
      WITH hTable
        DEBUG .Name
        sTableAndFields = .Name & "="
      END WITH 
      FOR EACH hField IN hTable.Fields
        WITH hField
          'DEBUG .Name
          sTableAndFields &= .Name & "+" 
        END WITH 
      NEXT       
    lsbxDbTables.Add(sTableAndFields)
    NEXT      
  ENDIF 
'  
END

Upd 3/11/2010: index start op 0.

Hoe een shell commando uitvoeren

Er zijn 2 mogelijkheden om commando’s naar het systeem te sturen:

EXEC en SHELL

EXEC start een extern process. SHELL start een extern command in een shell.
Bij EXEC geef je de parameters allemaal als parameter mee. Bij SHELL geef je een string met het hele commando mee.
EXEC [ "ls", "-la", "/tmp"] WAIT SHELL "ls -la /tmp" WAIT
EXEC wordt uitgevoerd in ? SHELL wordt uitgevoerd in /home/username
Gebruik bv
Application.path & "/this.txt"
voor een bestand dat in het Gambas programma-pakket zit (directory)
Test bv met
DIM sReturnValue AS String
SHELL "pwd" TO sReturnValue
DEBUG sReturnValue

Settings toepassing

Eenvoudige toepassing van Instellingen of configuratiebestand

Start een nieuw project met de naam ConfigSettings.
Kies bij Project Type, Options “File Settings Files Management”
Controle: Daardoor is onder project eigenschappen gb.settings aangekruist.

Vertrek op de nieuwe FMain form:
– maak een button bovenaan “btnShowConfig“.
– dubbelklik op de knop en vul er de volgende code in:

Message.Info(File.Load(Settings.path &/ Application.Name & ".conf"))
CATCH
Message.Error(Error.Text & " fout met config - bestaat niet? ")

= Een “run” levert normaal de foutmelding op.

Een beetje lager zet je een invultekstveld “txbxSetText1
Maak een nieuwe knop en zet die ernaast, met naam “btnSetText1” en zet in de code van click:

PUBLIC SUB btnSetText1_Click()

Settings["Instelling1"] = txbxSetText1.Text

END

= Een “run” doet niets nieuws lijkt op het eerste zicht. btnShowConfig geeft zelfde foutmelding. Je verlaat het programma.

= Een direkt daaropvolgende “run” met opvragen van btnShowConfig verrast misschien met je “instelling” van het tekstveld van de vorige “run”: onder een hoofding General (die je niet opgaf – standaard dus):

[General]
Instelling1=”txbxSetText1″

en een knop “ok”. Opeenvolgende “runs” tonen dat steeds de vorige ingevulde tekst, die je met btnSetText bevestigde, opgeslagen was.

Dat kan je terugvinden in de verborgen config directory:

/home/loginname/.config/gambas/

met de naam

ConfigSettings.conf

Open dat bestand met kate of een andere code-tekstverwerker en voeg een tweede “instelling” toe:

[General]
Instelling1="geheim"
Instelling2="nieuw"

Laat het programma lopen en vraag de instellingen op.

update 2012 11 30
Als je een configuratie-instelling opvraagt maar je bent niet zeker of die bestaat, geef je een standaardwaarde op die gebruikt moet worden bij ontbreken van de te zoeken instelling.

iHoogte = Settings[“General/Hoogte”, 120)

Als je wil testen of een configuratie-sleutel voorkomt of niet, zet je zelf “NULL” als alternatieve standaardwaarde.

IF isNull(Settings[“General/Runcounter”, NULL])
Settings[“General/Runcounter”] = 0
ENDIF

Objecten in Gambas: Hoe?

Ik probeer een zicht te krijgen op classes en objecten in Gambas. Er is een wel heel beperkt voorbeeld in de GUI aanwezig (Object – by juergen) waar een object met publieke string en integers wordt gemaakt (create) en vernietigd (destroy)
In de IDE wordt met een knop een object gemaakt en een waarde gegeven voor Name:
PUBLIC SUB btnCreateThing_Click()
myThing = NEW ClsThing
myThing.Name = "Dummy-Thing"

De class van het object, ClsThing:
' Gambas class file

PUBLIC Name AS String
PUBLIC X AS Integer
PUBLIC Y AS Integer
PUBLIC ID AS Integer

PUBLIC SUB tellaboutme() AS String

RETURN "I am: " & ME.Name & ", X= " & ME.X & ", Y= " & ME.Y & ", ID= " & ME.ID

END

De methode “tellaboutme” heb ik toegevoegd.

Nog uit te zoeken:
– hoe property initialiseren met een waarde (bv de X en de Y)
– hoe properties alleen leesbaar – niet wijzigbaar maken
(door ze onzichtbaar te maken en method voor uitlezen te gebruiken?)
– hoe zoiets als die ID als een serienummer van het object op een automatische manier laten initialiseren of toekennen bij creatie?
– hoe een verzameling van objecten maken, meer bepaald een array van objecten?
– hoe objecten opslaan (persistance?)

Er zijn volgens de documentatie een aantal speciale methodes vastgelegd:

_init Class initializatie.
_exit Class opkuisen.
_new Object instanciation.
_free Object vrijgeven.
_next Object or class enumeration.
_get Array read operator (lezen).
_put Array write operator (schrijven).
_call Om object of de class te gebruiken als een methode.
_unknown Een onbekende methode of eigenschap aanroepen.

Toegevoegd aan bovenstaand voorbeeld: zichtbaarheid en initialisatie van properties: screenshot en code:

Object, voorbeeld

de class: ClsThing:

' Gambas class file

PUBLIC sName AS String
PUBLIC iX AS Integer
PUBLIC iY AS Integer
PUBLIC iID AS Integer

PRIVATE iZ AS Integer
PRIVATE iSecret AS Integer

PUBLIC SUB _new()
  
  iZ = 5
  iSecret = 7
  iId = 1
  
END


PRIVATE SUB getSecret() AS Integer
  
  RETURN iSecret
  '  seems that the simple return function is not needed in the class as iSecret is reachable in the class
  ' from outside it is needed, but then the function must be public as with the next example of iZ:
  
END


PUBLIC SUB getZ() AS Integer
  
  RETURN iZ
  
END


PUBLIC SUB tellaboutme() AS String
  
  RETURN "I am: " & ME.sName & ", X= " & ME.iX & ", Y= " & ME.iY & ", Z= " & ME.getZ() & ", ID= " & ME.iID & " my secret is: " & iSecret
  
END

PUBLIC SUB increaseme(OPTIONAL i AS Integer)
  
  INC ME.iX
  INC ME.iY
  
END


en de form:FMain


' Gambas class file

PUBLIC myThing AS ClsThing

STATIC PUBLIC SUB Main()
  DIM myForm AS Form
  myForm = NEW FStart
  myForm.Show
END

PUBLIC SUB btCreateThing_Click()
  myThing = NEW ClsThing
  myThing.sName = "Dummy-Thing"
  ' properties reacheable from outside:
  mything.iX = 11
  mything.iY = 22
  mything.iID = 33 ' overwrites initialisation 
  txlbCheckResult.Text = "Created"
  txlbCheckResult.Visible = TRUE
  txlbCheckResult2.Text = ""
END

PUBLIC SUB btCheckThing_Click()
  txlbCheckResult.Text = myThing.sName & ", X= " & myThing.iX & ", Y= " & myThing.iY & ", ID= " & myThing.iID
'  iZ is not visible outside the class: (error: unknown symbol iZ in class ClsThing)
'  txlbCheckResult.Text &= ", Z= " & myThing.iZ
'  get it with a public method:
  txlbCheckResult.Text &= ", Z= " & myThing.getZ()
'  iSecret is not visible outside the class ..
'  txlbCheckResult.Text &= ", Secret = " & myThing.iSecret
'  .. and also the method is not visible (not public):
'  txlbCheckResult.Text &= ", Z= " & myThing.getSecret()
'  no way to get iSecret!  But it might -indirect- show up somehow:
  txlbCheckResult2.Text = myThing.tellaboutme()
CATCH
  Message(Error.Text)
END

PUBLIC SUB btDestroy_Click()
  myThing = NULL
  txlbCheckResult.Visible = FALSE
END



PUBLIC SUB Form_Open()

  

END

PUBLIC SUB btExit_Click()

  ME.Close

END

PUBLIC SUB btPlus_Click()

  myThing.increaseme()

END


Screenshot :

Object, voorbeeld

Probeer even samen te vatten:
Maak een classe:

  1. Maak een Class bij Classes, begint met C bv CProduct
  2. Er zijn automatisch een aantal _ bewerkingen gedefinieerd, zoals _init ( zie Gambas objects documentatie)
  3. Maak private objecten voor gebruik binnen de classe (bv een identity)
  4. Gebruik die waarden door een PUBLIC SUB te maken die de waarde teruggeeft
  5. Maak PUBLIC variabelen die rechtstreeks aangesproken mogen worden van buitenaf, bv een boolean switch “isValid”.
  6. Persisence: schrijf eventueel de database code in een externe Module; bv MData; je kan die dan aanpassen aan de gebruikte database zonder de objecten te wijzigen. Vanuit de classe spreek je die externe module aan; dus ze moet wel bestaan natuurlijk!

Declareer het object van die classe.
bv

PRIVATE hProduct AS CProduct

Maak er een variabele van:
bv

$hProduct = NEW CProduct

Als dat gebeurd is in de FMain kan je die aanspreken van elders met:
bv als name public is in de classe:

FMain.$hProduct.name

Eenvoudige grafieken met Gambas2

Article op Linux.com: “Creating simple charts with Gambas 2.0” van 12 december 2007 door Mark Alexander Bain.
Hij volgt een aantal conventies niet, en dat maakt de code moeilijker te lezen:
– Het type van een variabele wordt in Gambas aangegeven door een beginletter (bv iGetal, sNaam, …)
– Hij gebruikt in de namen van de variabelen veel “underscores” om twee delen van een woord te scheiden en die zo leesbaarder te maken. Maar in Gambas heeft die underscore een andere betekenis en wordt met hoofdletters in de woorden gewerkt, hoewel de underscores geen fouten geven in Gambas.
– Omdat er nogal veel met x en y coordinaten gewerkt wordt is het nodig meer betekenisvolle namen te geven.
x_string wordt dan sTitleX ; met 1 letter minder zeg je meer.

Hieronder (een stukje) “vertaalde” broncode:


' Gambas class file

PUBLIC SUB _new()

END

PUBLIC SUB Form_Open()

  drawChart()
  
END

SUB drawChart()
  
  DIM iOriginX AS Integer
  DIM iOriginY AS Integer
  DIM iMaxX AS Integer
  DIM iMaxY AS Integer
  DIM sTitleX AS String
  DIM sTitleY AS String
  
  'Initialize 
  DrawingArea1.Clear
  draw.Begin(DrawingArea1)
  
  ' Axis titles text
  sTitleX = "Value"
  sTitleY = "Date"
  
  ' Origin
  iOriginX = Len(sTitleX) * 10
  iOriginY = DrawingArea1.ClientH - 30
  
  ' Axis length
  iMaxX = DrawingArea1.Width
  iMaxY = DrawingArea1.Height * -1
  
  ' Axis draw
  draw.Line(iOriginX, iOriginY, iMaxX, iOriginY)
  draw.Line(iOriginX, iOriginY, iOriginX, iMaxY)
  
  ' Axis titles
  draw.Text(sTitleX, 0, iOriginY + iMaxY * 0.90)
  draw.Text(sTitleY, iMaxX * 0.90, iOriginY + 10) 
  
  draw.End
  
END

Rolluik: ComboBox als afrol-lijst (Drop-down list)

ComboBox De Combobox lijkt het meest op een gewone “drop down list” of rolluiklijst.
Toch gedraagt hij zich niet zo. Als je op de lijst klikt gaat die niet open, maar krijg je een “carrot” of cursor in het woord “ComboBox1” (knipperend vertikaal streepje).
De enige plek waar je de lijst kan doen openklappen is het pijltje rechts ernaast, en dat is in verhouding een klein vlak.
Om de hele oppervlakte op een klik te laten reageren met openklappen van de keuzelijst kan je het gedrag van “mousedown” definiëren:
Rechtsklik, Events, MouseDown brengt je in de code onder PUBLIC SUB ComboBox1_MouseDown() van de combobox. Voeg daar de “Popup” toe:

PUBLIC SUB ComboBox1_MouseDown()
ComboBox1.Popup()
END

Wil je de lijst nog “gevoeliger” maken kan je in plaats daarvan de lijst al laten openklappen als het pijltje er voorbijkomt:

PUBLIC SUB ComboBox1_enter()
ComboBox1.Popup()
END

Hoe je die lijst terug laat “inklappen” als je niet geselecteerd / geklikt hebt, heb ik niet gevonden.
(misschien met de _leave methode?)