Aktuelle Zeit: 22.07.2018 14:56

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 18 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Button soll Schleife unterbrechen (möglichst ohne Threads)
BeitragVerfasst: 11.07.2018 18:31 
Offline
Benutzeravatar

Registriert: 10.05.2005 22:48
Hallo,

in einem kleinen Tool wird aus dem "Suche starten"-Button nach Betätigung ein "Suche anhalten"-Button und es erfolgen diverse Aktionen:

Code:
ButtonGadget(#Suche,10,10,100,25,"Suche starten")

Repeat

EventID = WaitWindowEvent()

If EventID=#PB_Event_Gadget And EventGadget()=#Suche
 
  SetGadgetText(#Suche, "Suche anhalten")

  ; Hier diverse Schleifen die irgendwelches Zeug erledigen... 

EndIf

Until WaitWindowEvent() = #PB_Event_CloseWindow


Wie kann ich jetzt dem "Suche anhalten"-Button funktionsfähig machen? Er soll sozusagen die Suche abbrechen und sich selbständig auf "Suche starten" zurückändern.

Geht das ohne Threads?

Danke!

_________________
PB 5.70 LTS + Win 10


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Button soll Schleife unterbrechen (möglichst ohne Thread
BeitragVerfasst: 11.07.2018 19:02 
Offline
Benutzeravatar

Registriert: 21.08.2006 17:39
Hi,

ersteinmal würde ich die Eventschleife von der Aktionsschleife trennen.
Ansonsten werden deine Fensterevents nichtmehr abgearbeitet!
Und damit kommen wir schon auf die Lösung:
Den Aktionsthread einfach mit KillThread() mehr oder weniger freundlich abwürgen. ;)

Edit: ups. Du wolltest ohne Threads. Ich schreib was nachm Essen.

MFG
MIB

_________________
(hab alles, kann alles, weiß alles!!^^)

Bild


Zuletzt geändert von man-in-black am 11.07.2018 19:04, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Button soll Schleife unterbrechen (möglichst ohne Thread
BeitragVerfasst: 11.07.2018 19:03 
Offline
Ein Admin
Benutzeravatar

Registriert: 29.08.2004 20:20
Wohnort: Saarbrücken
Du kannst mit BindGadgetEvent() einen Callback für den Button erstellen und wenn dieser ausgelöst wird, kannst du den Wert einer globalen Variable so ändern, dass deine Schleife abgebrochen wird.
Allerdings ist das noch nicht alles. Damit Events überhaupt erst abgearbeitet werden, muss (Wait)WindowEvent() immer noch regelmäßig ausgeführt werden. In deiner Schleife musst du also regelmäßig weiter die Events abarbeiten. Am besten wäre zum Beispiel eine solche Schleife:
Code:
While WindowEvent() : Wend

Wenn kein Event kommt, ist WindowEvent() = 0 und somit geht es direkt nach der Schleife weiter. Kamen ein oder mehrere Events an, ist WindowEvent() solange nicht 0 bis alle anstehenden Events abgearbeitet sind. Und wenn der Event zufällig ein Klick auf den Abbruch-Button war, dann wird der Callback aufgerufen, die globale Variable geändert und du kannst die Schleife komplett abbrechen und wieder in die normale Event-Schleife zurückfallen.

Um dem Nutzer Feedback zu geben, dass er nur noch diesen einen Button klicken kann und sonst nichts, solltest du dann auch alle anderen Buttons im Fenster deaktivieren. Ansonsten werden in der Schleife aber sowieso alle Events des Nutzers ignoriert. Aber SplitterGadgets könnte man zum Beispiel immer noch nutzen, es sei denn auch das ist deaktiviert.

_________________
Freakscorner.de - Der Bastelkeller | Neustes Video: Creality 3D CR-10 Review und erste Druckergebnisse
Ubuntu Gnome 16.04.3 LTS x64, PureBasic 5.60 x64 (außerdem 4.41, 4.50, 4.61, 5.00, 5.10, 5.11, 5.21, 5.22, 5.30, 5.31, 5.40, 5.50)
"Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Button soll Schleife unterbrechen (möglichst ohne Thread
BeitragVerfasst: 11.07.2018 19:05 
Offline
Moderator
Benutzeravatar

Registriert: 05.10.2006 18:55
Wohnort: Rupture Farms
man-in-black hat geschrieben:
Den Aktionsthread einfach mit KillThread() mehr oder weniger freundlich abwürgen. ;)

Ich würde lieber eine globale Finish-/Stop-Variable definieren. Im Aktionsthread ist ja wahrscheinlich eine Schleife für das Durchsuchen und wenn die Finish-/Stop-Variable auf 1 ist, dann, wird die Schleife mit Break abgebrochen und der Aktionsthread wird sauber beendet ohne Memory Leaks.

_________________
BildBildBildBild
Bild | EnableExplicit ist kostenlos und vermeidet Fehler | Gib Goto keine Chance | Schneller als die Telekom erlaubt | Avira? Nein Danke
WinAPI forever | Bei Problemen bitte Beispielcode posten | Mit Adblock werbefrei, schneller und sicherer surfen | brain.exe ist der beste Schutz | Userlibrary ohne Source = NoGo


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Button soll Schleife unterbrechen (möglichst ohne Thread
BeitragVerfasst: 11.07.2018 19:34 
Offline
Benutzeravatar

Registriert: 21.08.2006 17:39
Ich bin immer für Chaos. ;)
Aber das hängt logischerweise natürlich von dem Schleifeninhalt/Aktionen ab.
Bei deiner Lösung ohne Threads sehe ich aber nach wie vor das Problem mit den Fensterevents. Wie willst du gleichzeitig deinen Button auswerten und Daten abarbeiten?
Das geht mMn nur mit einem zusätzlichen WindowEvent() und BindGadgetEvebt(). (S. Nic)
Das wiederum finde ich jedoch unschön, da du dann keine eindeutige Eventverarbeitung hast...

Was ist denn deine genaue Anwendung des Tools? Wieso keine Threads?

MFG
MIB

_________________
(hab alles, kann alles, weiß alles!!^^)

Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Button soll Schleife unterbrechen (möglichst ohne Thread
BeitragVerfasst: 11.07.2018 20:29 
Offline
Benutzeravatar

Registriert: 10.05.2005 22:48
Also Threads gehen natürlich auch notfalls ;) Dachte nur das wäre hier mir 2 Zeilen innerhalb der Schleife erledigt oder so...

Das heißt zwischen Repeat:Until kommen die Abfragen nach den Aktionen sowie ein While/Wend... und die eigentlichen "Arbeiten" werden unterhalb in Prozeduren (?) ausgelagert?

_________________
PB 5.70 LTS + Win 10


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Button soll Schleife unterbrechen (möglichst ohne Thread
BeitragVerfasst: 11.07.2018 20:41 
Offline
Benutzeravatar

Registriert: 10.05.2005 22:48
Ok jz hab ich den Thread vor den Code gepackt und diese Schleife:

Code:
Repeat

EventID = WaitWindowEvent()

If EventID=#PB_Event_Gadget And EventGadget()=#Suche
 
  If GetGadgetText(#Suche)="Suche starten"
    SetGadgetText(#Suche, "Suche anhalten")
   
    thread=CreateThread(@Suche(), 123)
  Else
    SetGadgetText(#Suche, "Suche starten")
    KillThread(thread)
   
  EndIf
   
EndIf

Until WaitWindowEvent() = #PB_Event_CloseWindow


Nicht sauber, funzt... aber er meckert wegen dem Code hier im Thread rum:

Code:
While GetGadgetAttribute(1, #PB_Web_Busy):WaitWindowEvent(1):Wend


[20:38:16] [ERROR] WindowEvent() und WaitWindowEvent() können nur vom Haupt-Thread aufgerufen werden.
[20:38:16] Die Programmausführung ist abgeschlossen.

Hab ich mich jetzt total verzettelt!? ;)

WaitWindowEvent(1) hab ich jetzt durch Delay(1) ersetzt.

Irgendwie reagiert der Button mit "Suche starten" aber nicht wirklich auf Anhieb :(

Auch der Fensterschließen-Button reagiert nicht wirklich sofort...

_________________
PB 5.70 LTS + Win 10


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Button soll Schleife unterbrechen (möglichst ohne Thread
BeitragVerfasst: 11.07.2018 21:47 
Offline
Benutzeravatar

Registriert: 21.08.2006 17:39
Hi,

da beide Threads unabhängig und parallel laufen, brauchst du auch nur in einem
der Threads die Eventstapel abarbeiten. Bei PB ist dies nativ nur im Hauptthread vorgesehen
(s. Fehlermeldung). Ergo brauchst du nur 1x (Wait)WindowEvent in Summe. Im Nebenthread
also nicht...
Dein Nebenthread kann maximal auf Fensterinhalte zugreifen. DAS ist aber mitunter
auch gefährlich, weil zeitgleich 2 Threads (Haupt- u. Nebenthread) auf die gleichen
Speicherbereiche zugreifen könnten. Hier würde ich lieber vom Nebenthread via custom Events
Dateien anfordern/übergeben und mit dem Hauptthread via Mutex in separate Speicherbereiche
ablegen. (Hätte ich mehr als ein Handy in der Hand, würde ich dir was zusammencoden ;) )

Code:
global Daten, endThread

Procedure Nebenthread
 While endThread = #false
 ...
    Rechne rechne
    PostEvent (#custom_holeMirDaten)
    ...
    Debug Daten

  Wend
  SetGadgetText(#button ... ;wieder auf normal setzen
Endprocedure

Repeat
  Event = WaitWindowEvent()

  Select Event
     ...
     Case #custom_holeMirDaten
         LockMutex...    ;vielleicht braucht man die Sicherheit hier auch nicht
             Daten = GetGadget...
         UnlockMutex

....
...
      Case #button      ;noch eine Fallunterscheidung, ob start oder stop
         endThread = #false

         CreateThread (Nebenthread)
         SetGadgetText(#button ...

         ;Statt killThread() - evt. auch mit Mutex sichern:
          EndThread = #true
         
 ...
Until Event = ...


(Das ist absoluter Pseudocode und vollkommen aus dem Kopf. Fehler sind somit wahrscheinlich!!)

MFG
MIB

_________________
(hab alles, kann alles, weiß alles!!^^)

Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Button soll Schleife unterbrechen (möglichst ohne Thread
BeitragVerfasst: 11.07.2018 23:28 
Offline
Benutzeravatar

Registriert: 27.02.2006 22:30
Wohnort: Neumünster
einfach denken !

dafür gibt es EventWindow() wenn PB Zeugs benutzt wird

bei Fremdzeugs muß dieses einen Abbruchbefehl haben, der in der Schleife abgefragt wird.

Code:
#main = 1
#suche = 1
#info = 2

Procedure irgendwelchesZeug(start)
   
   exit = 0
   
   For j = start To 10000
     
      ;mache irgendwelches Zeug z.B. 10000 Datensätze durchsuchen
     
      SetGadgetText(#info, Str(j))
     
      ;Prüfe auf Abbruch
      event = WindowEvent()
      If event = #WM_KEYDOWN
         If EventwParam() = #VK_ESCAPE
            exit = -1
            Break
         EndIf
         
      ElseIf event = #PB_Event_Gadget         
         If EventGadget() = #suche
            exit = j
            Break
         EndIf
      EndIf
     
      Delay(1)     
     
   Next
   
   ProcedureReturn exit
     
EndProcedure


OpenWindow(#main, 0, 0, 300, 300, "PureBasic Window", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)

ButtonGadget(#Suche,10,10,150,25,"Suche starten")

TextGadget(#info,10,60,150,25,"", #PB_Text_Center)

start = 1

Repeat
   
   Event = WaitWindowEvent()
   
   Select Event
         
      Case #PB_Event_Gadget
         
         If EventGadget() = #Suche
           
            SetGadgetText(#Suche, "Suche anhalten oder Esc")
                       
            ; Hier diverse Schleifen die irgendwelches Zeug erledigen... 
           
            x = irgendwelchesZeug(start)
           
            If x = -1   
               SetGadgetText(#info, "suche wurde abgebrochen")
               SetGadgetText(#Suche, "Suche starten"): start = 1
            ElseIf x = 0
               SetGadgetText(#info, "suche beendet")
               SetGadgetText(#Suche, "Suche starten"): start = 1
            Else               
               SetGadgetText(#info, "suche wurde angehalten bei " + Str(x))
               SetGadgetText(#Suche, "weitersuchen"): start = x
            EndIf
             
         EndIf
         
         
   EndSelect
   
   
Until Event = #PB_Event_CloseWindow 

_________________
Purebasic 5.60 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Button soll Schleife unterbrechen (möglichst ohne Thread
BeitragVerfasst: 12.07.2018 06:42 
Offline
Benutzeravatar

Registriert: 21.08.2006 17:39
Hi hjbremer,

das ist genau das Vorgehen, dass Nic und ich angedeutet haben.
Mir gefällt daran nur nicht, dass man quasi 2x die Eventbearbeitung durchführen muss.
Manchmal hat man Buttons, die auch während der Suche funktionieren sollen (Hilfe, ...).
Dein Code wird damit in sich redundant(!). BinGadgetEvent wäre eine Lösung,
aber was ist mit den anderen Events...?
Klar, alles möglich, aber für mich bleiben Threads die sauberste Lösung.

MFG
MIB

_________________
(hab alles, kann alles, weiß alles!!^^)

Bild


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 18 Beiträge ]  Gehe zu Seite 1, 2  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye