- 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).
Category Archives: Hoe – in Gambas
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/usernameGebruik bv Application.path & "/this.txt" voor een bestand dat in het Gambas programma-pakket zit (directory) Test bv met DIM sReturnValue AS String |
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:
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 :
Probeer even samen te vatten:
Maak een classe:
- Maak een Class bij Classes, begint met C bv CProduct
- Er zijn automatisch een aantal _ bewerkingen gedefinieerd, zoals _init ( zie Gambas objects documentatie)
- Maak private objecten voor gebruik binnen de classe (bv een identity)
- Gebruik die waarden door een PUBLIC SUB te maken die de waarde teruggeeft
- Maak PUBLIC variabelen die rechtstreeks aangesproken mogen worden van buitenaf, bv een boolean switch “isValid”.
- 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)
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?)