Frage zu Fenstern

Anfängerfragen zum Programmieren mit PureBasic.
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

Frage zu Fenstern

Beitrag von fabulouspaul »

Hallo zuasammen,

ich habe ein Problem, mit dem ich nicht voran komme.
Aus einem geöffneten Hauptfenster (mit Menü und ein paar Gadgets) rufe ich eine Prozedur auf, die einige Zeit benötigt um irgendwelche Dinge zu tun. Um dem Benutzer eine visuelle Rückmeldung zu geben, lasse ich in einem 2. kleinen Fenster eine ProgressBar anzeigen.
Wenn man nun während die Progressbar läuft in eines der Fenster klickt (manchmal auch erst nach ein paar Mal), bleibt die ProgressBar stehen und in der Titelzeile des 2. Fensters erscheint "(Keine Rückmeldung)". Das Programm arbeitet im Hintergrund aber weiter und wenn es fertig ist, kehrt es auch ins Hauptfenster zurück.

Hier mal eine Kurzfassung des Codes um zu zeigen was ich meine:

Code: Alles auswählen

;**** Fenster-Test ***


; Fenster
Enumeration
  #Window_0
  #Window_1
EndEnumeration

; Menüs
Enumeration
  #MenuBar_0
  #MENU_3   ;öffnen
  #MENU_4   ;schliessen
  #MENU_5   ;ende
EndEnumeration

;Gadgets
Enumeration
  #Frame3D_0
  #Frame3D_2
  #ProgressBar
  #StatusBar
  #StatusText
  #Text_0
EndEnumeration

Procedure Open_Window_0()  ; Hauptfenster
  If OpenWindow(#Window_0, 216, 0, 800, 550, "Viewer",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
    If CreateMenu(#MenuBar_0, WindowID(#Window_0))
      MenuTitle("Datei")
      MenuItem(#MENU_3, "Arbeiten")
      MenuItem(#MENU_4, "Schliessen")
      MenuItem(#MENU_5, "Ende")
    EndIf
    
    If CreateStatusBar(#StatusBar, WindowID(#Window_0))
      AddStatusBarField(300)
      AddStatusBarField(480)
      StatusBarText(#StatusBar, 0, "Programmstart")
      StatusBarText(#StatusBar, 1, "", #PB_StatusBar_Right)
    EndIf
    
    If CreateGadgetList(WindowID(#Window_0))
      Frame3DGadget(#Frame3D_0, 190, 0, 610, 90, "Aufnahme-Daten")
      Frame3DGadget(#Frame3D_2, 190, 90, 605, 415, "Image") 
    EndIf
  EndIf
EndProcedure

Procedure Open_Window_1()  ; Progress-Bar
  If OpenWindow(#Window_1, 216, 0, 270, 70, "Fortschrittanzeige",#PB_Window_WindowCentered, WindowID(#Window_0))
    If CreateGadgetList(WindowID(#Window_1))
      ProgressBarGadget(#ProgressBar, 10, 40, 250, 20, 0, 100, #PB_ProgressBar_Smooth)
      TextGadget(#StatusText, 20, 10, 230, 20, "Statusinformation", #PB_Text_Center)
    EndIf
  EndIf
  StickyWindow(#Window_1,1)
EndProcedure

Procedure Arbeite()
  
  Protected i
  Protected j
  
  Open_Window_1()
  
  For j = 1 To 10
    For i = 0 To 100 Step 1
      SetGadgetState(#ProgressBar, i) 
      Delay(10)
    Next

    For i = 100 To 0 Step -1
      SetGadgetState(#ProgressBar, i) 
      Delay(10)
    Next i
  Next j
  
  CloseWindow(#Window_1)
EndProcedure

Open_Window_0()
StatusBarText(#StatusBar, 0, "")

Repeat                                  ; Schleife Hauptfenster
 
  Event = WaitWindowEvent()             ; auf Ereignis warten
  WindowID = EventWindow()              ; welches Fenster?
  GadgetID = EventGadget()              ; welches Gadget?
  EventType = EventType()               ; welches Ereignis

  If WindowID = #Window_0               ; im Hauptfenster ist was passiert...

    Select Event
      Case  #PB_Event_Menu              ; Menü wurde gewählt 
        Select EventMenu()              ; welches Menü?
          Case #MENU_3                  ;  -> Arbeiten
            MessageRequester("Info", "Menü: Arbeiten")
            Arbeite()
          Case #MENU_4                  ;  -> Schliessen
            MessageRequester("Info", "Menü: Schliessen")
          Case #MENU_5                  ;  -> Ende
            MessageRequester("Info", "Menü: Ende")
            Goto Ende
        EndSelect
        
      Case #PB_Event_Gadget             ; Gadget wurde gewählt
        ;....
    EndSelect
     
  EndIf
Until WindowID = #Window_0 And Event = #PB_Event_CloseWindow ; Fenster schliessen

ende:
CloseWindow(#Window_0)
End    
Was mache ich denn da falsch? Vermutlich ist es etwas Grundlegendes, aber ich komme nicht drauf.

In diesem Sinne... guten Rutsch!
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Frage zu Fenstern

Beitrag von RSBasic »

1. Bitte benutze keine Sprungmarken (Goto). Das ist nicht sehr sinnvoll.
2. Wenn du die neuste Version von PureBasic benutzt, kannst du die Zeile "CreateGadgetList()" entfernen, da diese Funktion veraltet ist und nicht mehr gebraucht wird, weil diese Gadget-Liste automatisch beim Erstellen eines Fensters erstellt wird.
3. Warum dein Fenster sich aufhängt, liegt daran, dass die Haupt-Eventschleife gestoppt wird. Und zwar durch das Aufrufen deiner Prozedur "Arbeite()". Solange deine Prozedur ausgeführt wird, kann dein Fenster auch keine weiteren Events empfangen. Aus dem Grund hängt sich das Fenster auf.
Da ich grad keine Zeit habe, kann ich dir leider auch kein Lösungscode posten.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Waldixxl
Beiträge: 108
Registriert: 27.12.2005 17:35
Wohnort: Linz, Österreich

Re: Frage zu Fenstern

Beitrag von Waldixxl »

Hallo fabulouspaul

Du musst dafür sorgen das die Events abgeholt werden.
Zu Beispiel mit

Code: Alles auswählen

Procedure RefreshWindows(Durchlauf = 15)
      For i = 1 To Durchlauf
     WindowEvent()
   Next   
EndProcedure
Einfach in der Schleife von Arbeiten aufrufen.

Code: Alles auswählen

For j = 1 To 10
    For i = 0 To 100 Step 1
      SetGadgetState(#ProgressBar, i)
      Delay(10)
      RefreshWindows()
    Next

    For i = 100 To 0 Step -1
      SetGadgetState(#ProgressBar, i)
      Delay(10)
      RefreshWindows()
    Next i
  Next j
Guten Rutsch
Walter
Lesen bei schlechten Lichtverhältnissen ist nicht schlecht für die Augen, sondern trainiert sie sogar.

Linux Ubuntu Mate 18.04
PB 5.71
Intel i5
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Frage zu Fenstern

Beitrag von Nino »

Waldixxl hat geschrieben:Du musst dafür sorgen das die Events abgeholt werden.
Zu Beispiel mit

Code: Alles auswählen

Procedure RefreshWindows(Durchlauf = 15)
      For i = 1 To Durchlauf
     WindowEvent()
   Next   
EndProcedure
Wäre es nicht besser, alle noch in der Warteschlange befindlichen Ereignisse abzuarbeiten?

Code: Alles auswählen

Macro DoEvents
   While WindowEvent(): Wend
EndMacro
Als Alternative käme noch in Frage, den Hintergrundprozess in einem Thread auszuführen.

Allen einen Guten Rutsch wünscht
Nino
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

Re: Frage zu Fenstern

Beitrag von fabulouspaul »

Vielen Dank für die Hilfe!

Wie beschrieben hat es bereits geholfen, in der Arbeitsschleife regelmässig mal die Events abzuholen. :allright:
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

Re: Frage zu Fenstern

Beitrag von ts-soft »

fabulouspaul hat geschrieben:Wie beschrieben hat es bereits geholfen, in der Arbeitsschleife regelmässig mal die Events abzuholen. :allright:
Da damit aber nicht mehr auf die Eingaben des Benutzers reagiert wird / bzw. kann, sollte man alle Gadgets vorher disablen um den
Anwender nicht zur Weißglut anlaufen zu lassen!
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
fabulouspaul
Beiträge: 120
Registriert: 01.04.2011 21:59

Re: Frage zu Fenstern

Beitrag von fabulouspaul »

ts-soft hat geschrieben:
fabulouspaul hat geschrieben:Wie beschrieben hat es bereits geholfen, in der Arbeitsschleife regelmässig mal die Events abzuholen. :allright:
Da damit aber nicht mehr auf die Eingaben des Benutzers reagiert wird / bzw. kann, sollte man alle Gadgets vorher disablen um den
Anwender nicht zur Weißglut anlaufen zu lassen!
Guter Hinweis!
Das werde ich noch einbauen.
ozoffi
Beiträge: 41
Registriert: 08.02.2010 20:56

Re: Frage zu Fenstern

Beitrag von ozoffi »

Hallo!
Ihr habt auch mir mit diesem Beitrag sehr geholfen - danke!

Frage noch zum "Durchlauf": weshalb 15? Oder ist das unkritisch?
Benutzeravatar
HeX0R
Beiträge: 3040
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Frage zu Fenstern

Beitrag von HeX0R »

ozoffi hat geschrieben:Frage noch zum "Durchlauf": weshalb 15? Oder ist das unkritisch?
Nimm die Lösung von Nino, das andere ist relativ untauglich.
ozoffi
Beiträge: 41
Registriert: 08.02.2010 20:56

Re: Frage zu Fenstern

Beitrag von ozoffi »

Hallo!
Beides probiert - die For - Next Schleife funktioniert ... der Macro nicht wirklich.
Antworten