Seite 1 von 1

Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Mi, 06. Mai 2009 19:39
von Jan
Eine grundsätzliche Frage zur Propgrammiertechnik:

Ich muß Buttons erzeugen, die auch bestimmte, jeweils unterschiedliche Aktionen ausführen sollen. Die Action und die Caption sind je Button unterschiedlich, abhängig vom Inhalt eines übergebenen Arrays. Das sieht dann ungefähr so aus.

Code: Alles auswählen

For i := 1 TO Len(aArray)
    oBut := XbpPushButton():new(oParent, , aStart, aSize)
    oBut:caption := aArraay[i][1]
    oBut:acticate := aArray[i][2]
    oBut:create()
NEXT
Was nicht geht ist, die Action wie im Beispiel einfach an der Position im Array festzumachen, denn dann wird bei der Ausführung immer die letzte genommen, egal welcher Button geklickt wird. Weil ja i zum Ausführungszeitraum immer auf Len(aArray) steht.

Ich kann natürlich jeden Button einzeln erstellen. Aber das ist erstens viel zu aufwändig, gerade bei späteren Änderungen. Und was ist, wenn die Länge des Arrays vorher nicht bekannt ist? Ich kann doch nicht rein prophylaktisch 100 oder 200 Captions und 100 oder 200 Actions als LOCAL anlegen, nur weil ich die eventuell mal irgendwann so viele brauchen könnte. Oder muß ich das doch machen?

Jan

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Mi, 06. Mai 2009 20:16
von Martin Altmann
Hallo Jan,
habe nicht viel Zeit im Moment - suche doch mal im Forum nach "detached local", da findest Du die Lösung!

Viele Grüße,
Martin

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Mi, 06. Mai 2009 22:06
von Martin Altmann
Hallo Jan,
jetzt ist wieder ein wenig mehr Ruhe eingekehrt - also hier die Erklärung:
Ich vermute mal, in Deinem Array steht in der zweiten Spalte der auszuführende Codeblock in der Art "{ || ::TueWas(,,,,) }".
Ändere das doch mal in folgende Schreibweise: "|| ::TueWas(,,,,)" - lass also die {} weg.
Und dann kannst Du ja mal versuchen, in Deiner Schleife so vorzugehen:

Code: Alles auswählen

For i := 1 TO Len(aArray)
    oBut := XbpPushButton():new(oParent, , aStart, aSize)
    oBut:caption := aArraay[i][1]
    oBut:activate := &("{ " + aArray[i][2] + " }" )
    oBut:create()
NEXT
Viele Grüße,
Martin

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Do, 07. Mai 2009 7:07
von Jan
Hallo Martin,

ja, bei detached locals dämmert da langsam wieder was. :oops:

Allerdings mache ich das anders als Du annimmst. In aArray[2] steht ein Wert. Was damit gemacht werden soll ist bei allen Buttons das gleiche, nur der übergebene Wert in die auszuführende Funktion ist jeweils unterschiedlich.

Ich werde Deine Beispiele mal versuchen entsprechend anzupassen und sehen, ob ich damit klarkomme.

Jan

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Do, 07. Mai 2009 8:17
von Martin Altmann
Hallo Jan,
OK - dann so:

Code: Alles auswählen

For i := 1 TO Len(aArray)
    oBut := XbpPushButton():new(oParent, , aStart, aSize)
    oBut:caption := aArraay[i][1]
    oBut:activate := &("{ || ::TueWas( " + aArray[i][2] + " ) }" )
    oBut:create()
NEXT
Viele Grüße,
Martin

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Do, 07. Mai 2009 10:02
von Rolf Ramacher
Hi Jan,

ich weiß nicht, ob ich dich richtig verstanden habe. Aber könntest du nicht in einer For- Next Schleife die Buttons erzeugen ??
wenn dies von der Anzahl des Arrays abhängt ?? In aPos {} z.B. könntest du ja auch die Positionen der Pushbuttons eintragen und weieterzählen innerhalb der For-Next Schleife

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Do, 07. Mai 2009 10:29
von Jan
Rolf,

doch natürlich, mache ich ja auch. Schau Dir mein Beispiel an. Das Problem ist aber, daß die Werte in den Buttons dann nicht stimmen. Beispiel: Wenn da fogendes drin steht :activate := TueDasHier(aArray[2]), dann wird für jeden Button als "i" ein "Len(aArray) + 1" ausgeführt. Egal welchen Button ich drücke. Weil nun einmal zum Zeitpunkt des Klickes "i" auf diesem Wert steht.

Ich muß es also hinbekommen, das der Wert in TueDasHier() nicht "i" ist sondern sozusagen fest kodiert ist.

Jan

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Do, 07. Mai 2009 10:46
von Tom
@Jan: Und wie das genau geht, hat Dir Martin gerade gezeigt. Du musst dafür sorgen, dass der Codeblock tatsächlich den Wert enthält, den er ausführen soll, und das geht eben nicht "einfach" über die iterierende Variable. Wenn Du den Codeblock so baust, wie Martin skizziert hat, funktioniert das. Ich mache das tausendfach in meinen Apps.

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Do, 07. Mai 2009 10:47
von stevie
also wir machen das so.
Eine Klasse Button.
create - Methode:

Code: Alles auswählen

 local naLen, i, oBut

 ::aoBtn:= {}
 naLen:= len(aBtn)

 for i:= 1 to naLen
     oBut:= xbpPushButton():new (oDlg,, aBtn[i,1], aBtn[i,2], aPP)
     oBut:caption     := abtn[i,3]
     oBut:activate    := abtn[i,4]
     if aBtn[i,2] == NIL                // Groesse des Buttons nicht angegeben
        oBut:autosize :=.T.
     endif
     oBut:create()
     AAdd(::aoBtn, oBut)
  next
Array zur Übergabe an die Klasse sieht dann so aus.

Code: Alles auswählen

abtn:= { {{ 10,10}, {100,20} , "Button1", {|| Func1()}},;
             {{120,10}, {100,20} , "Button2", {|| Func2()}};
          }

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Do, 07. Mai 2009 11:17
von Jan
Tom,

ist mir schon klar. Das war jetzt auch nur als Erklärung für Rolf gedacht, um das dahinterstehende Problem aufzuzeigen. Ich werde das heute Abend mal nach Martins Vorgabe umsetzen und sehen, wie es läuft. Aber gut zu wissen, daß das schon geprüft läuft 8)

Stevie,

wie gesagt, bei mir ist das etwas anders, denn ich übergebe nicht die Funktion sondern nur eine Variable. Aber im Prinzip passt das schon.

Jan

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Fr, 08. Mai 2009 1:19
von AUGE_OHR
Jan hat geschrieben:Ich muß Buttons erzeugen
nachdem das mit den "detached local" geklärt ist, mal die Frage wegen der Buttons "an-und-für-sich".

wenn du wirklich mal mit Xbase++ 100 Buttons "malen" willst, dann wirst du merken das es eine ganze
Weile dauert bis die 100 Stück sich aufgebaut haben.

Du willst das ganze ja eh aus einem Array machen wo du ja die Koordinaten hast ...

also nimm doch ein Bitmap als Hintergrund für die Buttons und frage per Thread (ala Tooltip) auf
deine Koordinaten ab ob "da was ist". Man kann damit auch einen "Hover" Effekt erreichen.
Beim "clicken" kannst du ja dann den :LbDown Slot benutzen um den Codeblock zu aktivieren.

Ich würde ein imaginäres Gitter wie beim "Schiffe versenken" nehmen was dann auch bei einem :resize funktioniert.

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Fr, 08. Mai 2009 8:28
von Jan
Noch eine Zusatzfrage: Wie übergebe ich denn da Objekte oder Arrays?

Jan

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Fr, 08. Mai 2009 8:34
von Martin Altmann
Hallo Jan,
wo denn? Bei Jimmys Vorschlag?
Gar nicht - anhand der Koordinaten berechnest Du dann, auf das wievielte Array-Element geklickt wurde und liest aus der Position dann, was zu tun ist.

Viele Grüße,
Martin

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Fr, 08. Mai 2009 8:43
von Jan
Moin Martin,

nein, nicht Jimmys Vorschlag. Deiner. Dieser hier:

Code: Alles auswählen

oBut:activate := &("{ || ::TueWas( " + aArray[i][2] + " ) }" )
Und zusätzlich zu dem aArray[2] sollen noch ein komplettes Array und ein Objekt übergeben werden.

Jan

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Fr, 08. Mai 2009 8:51
von Martin Altmann
Moin Jan,
wie jetzt - an Deine Funktion?
Na dann speicher all die Sachen doch in Deinem Array. Oder verstehe ich Dich jetzt falsch?
Was spricht denn dagegen, Dein aArray entsprechend zu belegen?
Wenn da jetzt folgendes drin steht:

Code: Alles auswählen

aArray := { { "Bla", 1 },
            { "Blo", 2 },
            { "Ble", 3 } }
dann speicherst Du dort stattdessen halt:

Code: Alles auswählen

aArray := { { "Bla", { 1, Array1, Objekt1 } },
            { "Blo", { 2, Array2, Objekt2 } },
            { "Ble", { 3, Array3, Objekt3 } } }
Und Dein :activate bleibt unverändert und Du pfriemelst in Deiner :TueWas das übergebene Array auseinander.
Wenn Du das jedoch icht willst, steht in Deinem :activate dann halt:

Code: Alles auswählen

oBut:activate := &("{ || ::TueWas( " + aArray[i][2][1] + ", " + aArray[i][2][2] + ", " + aArray[i][2][3] + " ) }" )
Viele Grüße,
Martin

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Fr, 08. Mai 2009 8:58
von Jan
Hallo Martin,

hmm, sowas habe ich schon versucht. Array und Objekt kommen aber nicht ordentlich an.

Ich muß das noch mal nachvollziehen, vielleicht hatte ich da etwas irgendwas vertippt. Ich hatte das so gemacht (oder wollte das zumindest):

Code: Alles auswählen

oBut:activate := &("{ || ::TueWas( " + aArray[i][2] + ", " + aArray2 + ", " + oObjekt + " ) }" )
Ich weiß ja, warum ich Codeblöcke noch immer nur sparsam einsetze :x (Fast) jedes mal komm ich da irgendwie ins schwimmen.

Jan

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Fr, 08. Mai 2009 9:01
von Martin Altmann
Hallo Jan,
willst Du in jedem :activate-Codeblock das selbe Array und das selbe Objekt als Parameter übergeben?
BTW, wenn das Objekt der jeweilige Button sein soll, dann brauchst Du das Objekt latürnich nicht vorher im Array ablegen, sondern kannst es ja direkt im :activate-Codeblock mit referenzieren.

Viele Grüße,
Martin

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Fr, 08. Mai 2009 9:28
von Sören
Hallo Jan,

versuch's mal so:

Code: Alles auswählen

oBut:activate := &("{ || ::TueWas( " + aArray[i][2] + ", " + aArray2 + ", '" + Var2Bin( oObjekt ) + "' ) }" )
Anschließend den Binär-String mit Bin2Var() wieder zurückkonvertieren.

Re: Erzeuge Buttons in vorher unbekannter Anzahl

Verfasst: Fr, 08. Mai 2009 18:10
von Jan
Martin,

nein, nicht der eigene Button.

Sören,

das dürfte nicht gehen. Die aufgerufene Funktion wird auch noch von anderen Modulen angesprochen. Wo ich ein Bin2var nicht brauchen kann. Dann wär ich wieder bei dem Thema oben, daß ich alles umschreiben müsste.

Jan