Page 1 of 1

Specified Gadget is not initialised - from event=WaitWindowEvent

Posted: Sat Mar 02, 2024 9:48 pm
by matalog
When I press Key "e" to run the thread this program exits when debugging and reports:

[ERROR] program.pb (line 148)
[ERROR] The pecified #Gadget is not initialised

But line 148 contains

Code: Select all

  event=WaitWindowEvent()
Any ideas why?

Here is a version of the program that exhibits the problem:

Code: Select all

UseJPEGImageEncoder()


#width = 1350
#height = 1000


Enumeration
  #Menu_Escape
  #Menu_Space
  #Menu_W
  #Menu_C
  #Menu_E
  #Menu_P
  #Menu_O
  #Menu_A
  
EndEnumeration


Global s=1,a.d=0
Global drawleave=0
Define event
OpenWindow(0,0,0,1350,1000,"blahblah")
CreateImage(0,1350,900)
AddWindowTimer(0,0,50)
imgad=ImageGadget(#PB_Any, 0, 0, 1350, 900, ImageID(0))
AddKeyboardShortcut(0, #PB_Shortcut_Escape, #Menu_Escape)
AddKeyboardShortcut(0, #PB_Shortcut_Space, #Menu_Space)
AddKeyboardShortcut(0, #PB_Shortcut_W, #Menu_W)
AddKeyboardShortcut(0, #PB_Shortcut_C, #Menu_C)
AddKeyboardShortcut(0, #PB_Shortcut_E, #Menu_E)
AddKeyboardShortcut(0, #PB_Shortcut_P, #Menu_P)
AddKeyboardShortcut(0, #PB_Shortcut_O, #Menu_O)
AddKeyboardShortcut(0, #PB_Shortcut_A, #Menu_A)
sstring=StringGadget(#PB_Any,560*s,910*s,60,20,"1",#PB_String_LowerCase )
sgad=TextGadget  (#PB_Any, 540, 913*s, 45, 24, "S")
a1string=StringGadget(#PB_Any,30*s,910*s,50,20,"200",#PB_String_LowerCase )
a1gad=TextGadget  (#PB_Any, 10, 913*s, 45, 24, "A1")
a2string=StringGadget(#PB_Any,110*s,910*s,50,20,"200",#PB_String_LowerCase )
a2gad=TextGadget  (#PB_Any, 90, 913*s, 45, 24, "A2")
a3string=StringGadget(#PB_Any,190*s,910*s,50,20,"200",#PB_String_LowerCase )
a3gad=TextGadget  (#PB_Any, 170, 913*s, 45, 24, "A3")
a4string=StringGadget(#PB_Any,270*s,910*s,50,20,"200",#PB_String_LowerCase )
a4gad=TextGadget  (#PB_Any, 250, 913*s, 45, 24, "A4")
f1string=StringGadget(#PB_Any,30*s,940*s,50,20,"411",#PB_String_LowerCase )
f1gad=TextGadget  (#PB_Any, 10, 943*s, 45, 24, "F1")
f2string=StringGadget(#PB_Any,110*s,940*s,50,20,"411",#PB_String_LowerCase )
f2gad=TextGadget  (#PB_Any, 90, 943*s, 45, 24, "F2")
f3string=StringGadget(#PB_Any,190*s,940*s,50,20,"444",#PB_String_LowerCase )
f3gad=TextGadget  (#PB_Any, 170, 943*s, 45, 24, "F3")
f4string=StringGadget(#PB_Any,270*s,940*s,50,20,"444",#PB_String_LowerCase )
f4gad=TextGadget  (#PB_Any, 250, 943*s, 45, 24, "F4")
spinxstring=StringGadget(#PB_Any,350*s,910*s,50,20,"200",#PB_String_LowerCase )
spinxgad=TextGadget  (#PB_Any, 330, 913*s, 45, 24, "SX")
spinystring=StringGadget(#PB_Any,350*s,940*s,50,20,"200",#PB_String_LowerCase )
spinygad=TextGadget  (#PB_Any, 330, 943*s, 45, 24, "SY")
gstring=StringGadget(#PB_Any,440*s,910*s,60,20,"0.000005",#PB_String_LowerCase )
gsgad=TextGadget  (#PB_Any, 420, 913*s, 45, 24, "T")
p1string=StringGadget(#PB_Any,520*s,940*s,50,20,"0",#PB_String_LowerCase )
p1gad=TextGadget  (#PB_Any, 500, 943*s, 45, 24, "P1")
p2string=StringGadget(#PB_Any,600*s,940*s,50,20,"0",#PB_String_LowerCase )
p2gad=TextGadget  (#PB_Any, 580, 943*s, 45, 24, "P2")
opvstring=StringGadget(#PB_Any,620*s,970*s,50,20,"0",#PB_String_LowerCase )
opvgad=TextGadget  (#PB_Any, 590, 973*s, 45, 24, "OPV")
p3string=StringGadget(#PB_Any,680*s,940*s,50,20,"0",#PB_String_LowerCase )
p3gad=TextGadget  (#PB_Any, 660, 943*s, 45, 24, "P3")
p4string=StringGadget(#PB_Any,760*s,940*s,50,20,"0",#PB_String_LowerCase )
p4gad=TextGadget  (#PB_Any, 740, 943*s, 45, 24, "P4")
opacity=StringGadget(#PB_Any,760*s,970*s,50,20,"80",#PB_String_LowerCase )
opgad=TextGadget  (#PB_Any, 740, 973*s, 45, 24, "OP")
d1string=StringGadget(#PB_Any,30*s,970*s,50,20,"0",#PB_String_LowerCase )
d1gad=TextGadget  (#PB_Any, 10, 973*s, 45, 24, "d1")
d2string=StringGadget(#PB_Any,110*s,970*s,50,20,"0",#PB_String_LowerCase )
d2gad=TextGadget  (#PB_Any, 90, 973*s, 45, 24, "d2")
d3string=StringGadget(#PB_Any,190*s,970*s,50,20,"0",#PB_String_LowerCase )
d3gad=TextGadget  (#PB_Any, 170, 973*s, 45, 24, "d3")
d4string=StringGadget(#PB_Any,270*s,970*s,50,20,"0",#PB_String_LowerCase )
d4gad=TextGadget  (#PB_Any, 250, 973*s, 45, 24, "d4")
astring=StringGadget(#PB_Any,350*s,970*s,50,20,"0",#PB_String_LowerCase )
astrgad=TextGadget  (#PB_Any, 330, 973*s, 45, 24, "A")
aonstring=StringGadget(#PB_Any,440*s,970*s,50,20,"1",#PB_String_LowerCase )
aongad=TextGadget  (#PB_Any, 410, 973*s, 45, 24, "Aon")
bstring=StringGadget(#PB_Any,520*s,970*s,50,20,"0",#PB_String_LowerCase )
bstrgad=TextGadget  (#PB_Any, 500, 973*s, 45, 24, "B")
save_button=ButtonGadget(#PB_Any,850*S,910,60,30,"SAVE")
stop_button=ButtonGadget(#PB_Any,850*S,970,60,30,"CANCEL")
idstgad=StringGadget(#PB_Any,1000*s,970,80,25,"IDLE",#PB_Text_Center)
valgad=StringGadget(#PB_Any,1000*s,940,80,25,"0",#PB_Text_Center)
f1.d=ValD(GetGadgetText(F1string)):f2.d=ValD(GetGadgetText(F2string)):f3.d=ValD(GetGadgetText(F3string)):f4.d=ValD(GetGadgetText(F4string))


Procedure Save(null)
  Shared image, a1string,a2string,a3string,a4string,f1string,f2string,f3string,f4string,spinxstring,spinystring,gstring,P1STRING,P2STRING,P3STRING,P4STRING,sstring,d1string,d2string,d3string,d4string,aonstring,bstring
  a1.d=ValD(GetGadgetText(a1string)):a2.d=ValD(GetGadgetText(a2string))
  a3.d=ValD(GetGadgetText(a3string)):a4.d=ValD(GetGadgetText(a4string))
  d1.d=ValD(GetGadgetText(d1string)):d2.d=ValD(GetGadgetText(d2string)):d3.d=ValD(GetGadgetText(d3string)):d4.d=ValD(GetGadgetText(d4string))
  f1.d=ValD(GetGadgetText(F1string)):f2.d=ValD(GetGadgetText(F2string)):f3.d=ValD(GetGadgetText(F3string)):f4.d=ValD(GetGadgetText(F4string))
  p1.d=ValD(GetGadgetText(P1string)):p2.d=ValD(GetGadgetText(P2string)):p3.d=ValD(GetGadgetText(P3string)):p4.d=ValD(GetGadgetText(P4string))
  spinx.d=ValD(GetGadgetText(spinxstring)) :spiny.d=ValD(GetGadgetText(spinystring))
  fname$="blabla"+"-"+FormatDate("%yyyy%mm%dd_%hh%ii%ss", Date())+"-"+"a1="+StrD(a1)+"a2="+StrD(a2)+"a3="+StrD(a3)+"a4="+StrD(a4)+"d1="+StrD(d1)+"d2="+StrD(d2)+"d3="+StrD(d3)+"d4="+StrD(d4)+"p1="+StrD(p1)+"p2="+StrD(p2)+"p3="+StrD(p3)+"p4="+StrD(p4)+"f1="+StrD(f1)+"f2="+StrD(f2)+"f3="+StrD(f3)+"f4="+StrD(f4)+".jpg"
  
  If SaveImage(4,fname$, #PB_ImagePlugin_JPEG,10)
    
    
  EndIf
  
EndProcedure





Procedure.l HSV(Hue.d, Saturation.d, Value.d)
  Protected H.i = Int(Hue/60)
  Protected f.d = 1-Pow(Cos((Hue/60-H)*#PI/2), 2)
  Protected Sat.d = Saturation/100
  If Sat > 1.0 : Sat = 1.0 : ElseIf Sat < 0.0 : Sat = 0.0 : EndIf
  Protected V.d = Value * 2.55
  If V > 255 : V = 255 : ElseIf V < 0 : V = 0 : EndIf
  Protected p.i = V * (1-Sat)
  Protected q.i = V * (1-Sat*f)
  Protected t.i = V * (1-Sat*(1-f))
  Select H
    Case 1 : ProcedureReturn RGB(q,V,p)
    Case 2 : ProcedureReturn RGB(p,V,t)
    Case 3 : ProcedureReturn RGB(p,q,V)  
    Case 4 : ProcedureReturn RGB(t,p,V)
    Case 5 : ProcedureReturn RGB(V,p,q)  
    Default : ProcedureReturn RGB(V,t,p)
  EndSelect
EndProcedure


Procedure Draw(null)
  drawleave=0
  
  Shared image, a1string,a2string,a3string,a4string,f1string,f2string,f3string,f4string,spinxstring,spinystring,gstring,P1STRING,P2STRING,P3STRING,P4STRING,sstring,d1string,d2string,d3string,d4string,aonstring,bstring,s,opacity,imgad,opvstring
  
  SetGadgetText(idstgad,"IDLE")
  
  
EndProcedure

Repeat 
  
  event=WaitWindowEvent()
  
  If Event = #PB_Event_Timer
    SetGadgetText(valgad,StrD(a/(8*#PI)*100))
  EndIf    

  gadget=EventGadget()

  Select event
    Case #PB_Event_Menu
      Select EventMenu()
        Case #Menu_C
          
        Case #menu_E
          If IsThread(th)=0
            SetGadgetText(idstgad,"BUSY")
            th=CreateThread(@Draw(),0)
          EndIf
          
        Case #Menu_O
          
        Case #Menu_P
          
        Case #Menu_Escape
          quit = #True
        Case #Menu_Space
          Delay(800)
        Case #Menu_W
          SaveImage(4,"Randraw2024 - "+FormatDate("%yyyy%mm%dd_%hh%ii%ss", Date())+Str(Random(9999,1))+".jpg", #PB_ImagePlugin_JPEG,99)
          save=save+1
      EndSelect
  EndSelect

  If event=#PB_Event_Gadget
    Select gadget
      Case save_button
        CreateThread(@Save(),0)
        
      Case stop_button
        drawleave=1
    EndSelect
  EndIf
  
Until quit=#True

End 

Re: Specified Gadget is not initialised - from event=WaitWindowEvent

Posted: Sat Mar 02, 2024 10:26 pm
by Caronte3D
Don't update gadgets directly from threads.
Also, the "idstgad" variable is local, so you can't access it from thread

Re: Specified Gadget is not initialised - from event=WaitWindowEvent

Posted: Sat Mar 02, 2024 10:38 pm
by matalog
I had previously got an answer to another question, to use a threaded drawing routine instead of not, and the suggested thread is the 5th reply down in this post: https://www.purebasic.fr/english/viewto ... ad#p593022 it clearly uses a gadget in the thread, and was my reason for doing so from then on.

Do you have an explanation to what is wrong with using that gadget in the thread? Others seems to think it was okay.

Yes, I saw that I neglected to share that variable with the procedure - that would have been a better error to receive :-). Would EnableExplicit() have helped there? It is working now.

Re: Specified Gadget is not initialised - from event=WaitWindowEvent

Posted: Sun Mar 03, 2024 1:25 am
by mk-soft
Gadget changes from threads only work partially from threads on Windows.
On Linux and macOS this leads to a crash.
See signature ThreadToGUI

Re: Specified Gadget is not initialised - from event=WaitWindowEvent

Posted: Sun Mar 03, 2024 10:50 am
by infratec

Code: Select all

EnableExplicit
:!: :!: :!:

And:

Code: Select all

Procedure Draw(idstgad)
:
:
:
th = CreateThread(@Draw(), idstgad)

Re: Specified Gadget is not initialised - from event=WaitWindowEvent

Posted: Sun Mar 03, 2024 10:52 am
by infratec
And in MacOS your code will fail 100%

But even with PostEvent() it is tricky in MacOS, if the main event loop is already terminated and not longer runninng.

Re: Specified Gadget is not initialised - from event=WaitWindowEvent

Posted: Sun Mar 03, 2024 2:18 pm
by mk-soft
macOS does not like it when threads are still running when the program is closed.

Re: Specified Gadget is not initialised - from event=WaitWindowEvent

Posted: Sun Mar 03, 2024 2:36 pm
by infratec
All threads are closed before exit.
But I had an external lib with callback for an event and I used PostEvent to add a message to a queue.
When the main loop is no longer running and the PostEvent was fired, the program crashes.
The extarnal lib is terminated correct before the program is finished.

I needed to add a global variable for program exit and avoid to send the PostEvent() after the main loop was finished.