Verständnisfrage zu Fenstern

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
ne555
Beiträge: 24
Registriert: 12.01.2008 03:29

Verständnisfrage zu Fenstern

Beitrag von ne555 »

Zu meiner ersten Programmieraufgabe „Multimeter-Visualisierung“ habe ich eine Verständnisfrage.
Von meinem Multimeter wird ein String übergeben den ich im Sekundentakt ausgeben möchte.
Das Auslesen vom Multimeter klappt hervorragend.
Da ich merke, das der Einstieg in PB für mich doch nicht so einfach ist wie ich gedacht hatte (komme von der SPS Programmierung in C), zerlege ich Gesamt-Konzept in kleine Abschnitte, die ich dann jedes für sich löse und am Schluß alles zusammenfüge.
Das ist glaube ich das Beste um die einzelnen Funktionalitäten in PB zu verstehen.

Mein momentaner Teilbereich ist die periodische Ausgabe (sekündlich) eines Strings nach Anklickens eines Start-Buttons, sowie das Beenden der Ausgabe bei klick auf den Stop-Button.
Funktioniert: Mir fällt nun folgendes auf:
Wenn ich die Repeat Schleife auskommentiere, also nur noch die If OpenWindow Abfrage abgearbeitet wird, wird nur ein leeres Fenster angezeigt.
Warum?
und was löst die Darstellung der ButtonGadgets aus?

Nach meinem Verständnis müsste die If OpenWindows Abfrage zur korrekten Darstellung des Fensters doch ausreichen.

Code: Alles auswählen

MessString.s ="TE  0022    +CR" ;String wie er von Messgerät gesendet wird
Start.b
Stop.b
StartTime.l
StopTime.l 
Timer.l = 0
StartTimer.l = 0
Zaehler.l



 If OpenWindow(0,100,100,640,480,"Mess-Wert-Erfassug",#PB_Window_SystemMenu)
     CreateGadgetList(WindowID(0))
     ButtonGadget(1,20,20,100,20,"Start")
     ButtonGadget(2,20,80,100,20,"Stop")
     ListViewGadget(3,150,20,400,200)
 EndIf 
    
  Repeat
    EventID = WindowEvent()
      If EventID = #PB_Event_CloseWindow 
        Quit = 1
      EndIf
      
      If EventID = #PB_Event_Gadget
         If EventGadget()=1
            Start      = 1
            Stop       = 0
            AddGadgetItem(3,-1,"Starte Aufzeichnung    Start="+Str(Start)+" Stop= "+Str(Stop))
        EndIf
        
        If EventGadget()=2
           Start      = 0
           Stop       = 1
           Zaehler    = 0
           StartTimer = 0
           AddGadgetItem(3,-1,"Aufzeichnung beendet     Start="+Str(Start)+" Stop= "+Str(Stop)+" Zaehler = "+Str(Zaehler))
        EndIf
      EndIf 
      
      If Start = 1
         If StartTimer = 0
            StartTime  = ElapsedMilliseconds()
            StopTime   = StartTime + 1000
            StartTimer = 1
         EndIf
         If StartTimer = 1
            StartTime  = ElapsedMilliseconds()
            If StartTime >= StopTime  
               Zaehler = Zaehler + 1
               AddGadgetItem(3,-1,"String= "+ MessString + "   Zaehler= "+Str(Zaehler)+"   Start "+Str(StartTime)+"  Stop "+Str(StopTime))
               StartTimer = 0
            EndIf  
         EndIf
      EndIf
          
    Until Quit=1

;Delay(4000)
End
Grüße ne555
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Verständnisfrage zu Fenstern

Beitrag von Kiffi »

ne555 hat geschrieben:Wenn ich die Repeat Schleife auskommentiere, also nur noch die If OpenWindow Abfrage abgearbeitet wird, wird nur ein leeres Fenster angezeigt. Warum?
Du musst bedenken, dass das Fenster auch neu gezeichnet werden muss. So
ein Refresh ist ebenfalls ein Event, welches in der Event-Schleife
(automatisch) gehandelt wird. Keine Event-Schleife, kein Redraw, leeres
Fenster.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
ne555
Beiträge: 24
Registriert: 12.01.2008 03:29

Beitrag von ne555 »

Was muß ich denn dann in den code ( bei auskommentierter Repeat-Schleife) einfügen, um ein vollständiges Fenster zu erhalten?
(aller Anfang ist schwer) /:->
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

ne555 hat geschrieben:Was muß ich denn dann in den code ( bei auskommentierter Repeat-Schleife) einfügen, um ein vollständiges Fenster zu erhalten?
(aller Anfang ist schwer) /:->
Die Repeat-Schleife natürlich :wink:

Hier mal einen Blick reinwerfen:
http://www.purearea.net/pb/download/tut ... ndling.htm
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ne555
Beiträge: 24
Registriert: 12.01.2008 03:29

Beitrag von ne555 »

Das ist ein sehr gutes Tutorial.
Danke sehr.
Gibt es mehr von dieser Art?
Wenn ich nur "SK_EventHandling.htm"
aus der URL lösche kommt leider nix mehr
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Oben rechts auf http://purearea.net clicken oder in den Browser eingeben. Dort
einfach Tutorials auswählen.
Viele Tutorials sind aber veraltet, bzw. laufen nicht ohne Änderungen in der
aktuellen Version. In dem Tutorial über Events, solltest Du alles Ignorieren,
was WindowEvent() oder Delay verwendet. Als Ersatz mal den optionalen
Parameter für WaitWindowEvent(timeout) ausprobieren.
Für Dein Programm wäre sicherlich auch ein Timer sinnvoll, einfach mal
die Forensuche bemühen: Timer, HighResTimer, MultimediaTimer usw.,
wobei der normalle WindowsTimer wahrscheinlich genügen sollte.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ne555
Beiträge: 24
Registriert: 12.01.2008 03:29

Beitrag von ne555 »

aha, dann gibt es also doch timer. Als ich in der Hilfe gesucht habe, kam nur die ElapsedMilliseconds() Funktion, aber damit funktionierts ja ganz ordentlich. Leider habe ich nicht überall Zugriff aufs Internet, so das ich wenn ich Tagsüber mal ein wenig Leerlauf habe, auf die normale Hilfe beschränkt bin. Ich bin schon ein schönes Stück vorangekommen. Morgen schau ich mir mal die String verarbeitung an.

Grüße ne555
Benutzeravatar
ne555
Beiträge: 24
Registriert: 12.01.2008 03:29

optimierung (cpu auslastung)

Beitrag von ne555 »

Dieser Abschnitt ist soweit fertig.
Die Tasten sind gegeneinander Verriegelt, der String den das Messgerät sendet wird zerlegt und im Sekundentakt ausgegeben. Mhmm sind eigentlich nur IF Abfragen drin........na ja
Ich habe hier schon so einiges in Bezug auf Ablaufoptimierung gelesen.
Daher fällt mir auf:
Wenn ich das Programm starte geht die CPU-Auslastung sofort auf 100%.
Wo muss ich ansetzen, wenn ich den vorhandenen Code optimieren möchte?
Oder kann ich die CPU Auslastung mit dem Debuger-Modus gar nicht bewerten?

Dann noch eine wahrscheinlich dumme Frage:
Wo zum Geier ist bei PB die Schaltfläche zum Ausdrucken des Codes. Unter Datei kann ich nichts finden und bei den Einstellungen find ich auch keinen Hinweis dazu.
Muss ich etwa wirklich alles in den Win-Editor kopieren, um es von dort aus auszudrucken?

Code: Alles auswählen

; Variablen deklaration
Start.b      = 0
Stop.b       = 1
StartTime.l  = 0
StopTime.l   = 0
Timer.l      = 0
StartTimer.l = 0
Zaehler.l    = 0
test.l       = 0
Time.s       = FormatDate("%dd:%mm:%yyyy:%hh:%ii:%ss", Date()) ; aktuelle Zeit auslesen
Timeref.s    = Time
Richtund.b   = -1
AusZeit.l    = 2000

; String-Variablen
Global Bereich.s    =""
Global Messwert1.s  =""
Global Messwert2.s  =""
Global Pol.s        =""
Global MA.s         =""
Global MessString.s ="TE  0022    +CR" ;String wie er von Messgerät gesendet wird

Datum.s   = Left(Time, 10)
Uhrzeit.s = Right(Time, 8)


Procedure MessStr()
MB.s

MB = Left(MessString,2)
If MB ="TE" 
   Bereich = "Temperatur"
   MA      = "°C"
EndIf

Messwert1 = Mid(MessString,5,2)
Messwert2 = Mid(MessString,7,2)
Pol       = Mid(MessString,13,1)   


EndProcedure



; Hauptprogramm
 If OpenWindow(0,100,100,640,480,"Mess-Wert-Erfassug",#PB_Window_SystemMenu)
     CreateGadgetList(WindowID(0))
     ButtonGadget(1,20,50,100,20,"Start")
     ButtonGadget(2,20,90,100,20,"Stop")
     ListViewGadget(3,150,20,400,300)
     ButtonGadget(4,20,130,100,20,"Beenden")
     
     TextGadget(6,20,200,100,20, Bereich, #PB_Text_Border | #PB_Text_Center)
     TextGadget(7,5,240,20,20, Pol, #PB_Text_Border | #PB_Text_Center)
     TextGadget(8,25,240,30,20, Messwert1, #PB_Text_Border | #PB_Text_Center)
     TextGadget(9,55,240,30,20, Messwert2, #PB_Text_Border | #PB_Text_Center)
     TextGadget(10,85,240,60,20, MA, #PB_Text_Border | #PB_Text_Center)
     TextGadget(11,10,20,60,20, Datum, #PB_Text_Border | #PB_Text_Center)
     TextGadget(12,80,20,60,20, Uhrzeit, #PB_Text_Border | #PB_Text_Center)
 EndIf 
    
  Repeat ; begin Hauptschleife
  
    Time  = FormatDate("%dd:%mm:%yyyy:%hh:%ii:%ss", Date()) ; aktuelle Zeit auslesen
    
    EventID = WindowEvent()
      If EventID = #PB_Event_CloseWindow ; Auf Seite schließen abfragen 
         Quit = 1
      EndIf
      
      If EventID = #PB_Event_Gadget ; Auf Gadget Event abfragen
         If Stop = 1  ; Auf Button Start abfragen
            If EventGadget()=1
               Start      = 1
               Stop       = 0
               AddGadgetItem(3,Richtung,"Starte Aufzeichnung          :" + Time) 
               If Richtung = -1
                  Richtung = 1
               EndIf    
            EndIf
         EndIf  
        
       If Stop = 0 ; Auf Button Stop abfragen
        If EventGadget()=2
           Start      = 0
           Stop       = 1
           Zaehler    = 0
           StartTimer = 0
           AddGadgetItem(3,1,"Aufzeichnung beendet      :" + Time) 
        EndIf
       EndIf 

        If EventGadget()=4 ; Auf Button beenden abfragen
           If Start = 1
              AusZeit = 2000
            Else
              AusZeit = 1
           EndIf      
           AddGadgetItem(3,1,"Aufzeichnung beendet      :" + Time) 
           Ende  = 1
        EndIf
      EndIf 

      
      If Start = 1 ; Polling intervall
         If StartTimer = 0
            StartTime  = ElapsedMilliseconds()
            StopTime   = StartTime + 1000
            StartTimer = 1
         EndIf
         If StartTimer = 1
            StartTime  = ElapsedMilliseconds()
            If StartTime >= StopTime  
               Zaehler = Zaehler + 1
               AddGadgetItem(3,1,"String= "+ MessString + "   Index= "+Str(Zaehler))
               StartTimer = 0
               MessStr()
               ; aktualisieren der Anzeigen (Text Gadget)
               SetGadgetText(6, Bereich)
               SetGadgetText(7, Pol)
               SetGadgetText(8, Messwert1)
               SetGadgetText(9, Messwert2)
               SetGadgetText(10, MA)  
            EndIf  
         EndIf
     EndIf
     
     If Ende = 1  ; Reaktion auf Beenden-Button (mit Aufzeichnung beenden)
        test  = test + 1
        If test = 3
           Quit = 1
           Ende = 0
           test = 0
        EndIf   
     EndIf
        
     ; aktualisieren der Zeit-Anzeige (Text Gadget)
     If Timeref <> Time
        Datum.s   = Left(Time, 10)
        Uhrzeit.s = Right(Time, 8)
        SetGadgetText(11, Datum)
        SetGadgetText(12, Uhrzeit)
        Timeref = Time
     EndIf      
 
   Until Quit=1 ; Hauptschleife beenden
Delay(AusZeit)   ; Verzögerung bei Programm-Ende
End
[/code]
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: optimierung (cpu auslastung)

Beitrag von Kiffi »

ne555 hat geschrieben:Wenn ich das Programm starte geht die CPU-Auslastung sofort auf 100%.
Wo muss ich ansetzen, wenn ich den vorhandenen Code optimieren möchte?
Kapitel 3 (WindowEvent()) in dem von Thomas geposteten Tutorial lesen ;-)

// Edit:

Oder mit WaitWindowEvent(Timeout.l) arbeiten (gab es zu Zeiten des
Tutorials IMO noch nicht)

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Bloß kein WindowEvent() oder Delay :mrgreen:
http://www.purebasic.fr/german/viewtopi ... 561#109561
Dritter Beispielcode!

In das Timercallback packste alles was mit Deiner Messung zu tun hat.
ElapsedMilliseconds() brauchste dann auch nicht mehr.

Im Eventloop fragste nur das Beenden und die Buttons ab, nicht mehr, aber
mit WaitWindowEvent() !!

Dann haste nen funktionierendes Fenster, keine CPU-Belastung, keine Titel-
leiste mit "... keine Rückmeldung" :mrgreen:

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten