show a loading panel while a panel is not ready yet

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Mamo_Grag17
Earned some good credits
Earned some good credits
Posts: 107
Joined: Thu Mar 31, 2022 7:45 pm
Location: Morocco

show a loading panel while a panel is not ready yet

Post by Mamo_Grag17 »

In my code, there is a panel, let's name it noteBookPanel, this panel takes somehow a long time to show, during that time i want to show a loading panel for the user. But this panel is added to wxNoteBook and i will be making a lot of noteBookPanel and show them using notebook. now there is a problem that i want to run a two threads, both of them will run after a mouse event, the first one will make a panel and add it to the notebook, the second one will keep checking if the panel the i make is ready, if it is not ready it will still show the loading panel.

this is the code:

Code: Select all

void noteBook::onWheel(wxMouseEvent& event)
{

  if (event.GetWheelRotation() > 0)
  {
    if (currentPanel > 1)
    {
      currentPanel--;
      this->SetSelection(currentPanel);
    }
    
  }
  else{
    if (currentPanel == total)
    {
     /* 
     i want to show a loading panel as of here
     */
      currentPanel++;
      total++;

      noteBookPanel * newPanel = new noteBookPanel(this);
      this->AddPage(newPanel,"");
      this->SetSelection(currentPanel); //until it is changed by this function
    }
    else
    {
     currentPanel++;
     this->ChangeSelection(currentPanel);
    }
  }

}
the problem is that i didn't know how to check if newPanel is ready to use, i tried to check the docs but nothing.
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: show a loading panel while a panel is not ready yet

Post by doublemax »

Mamo_Grag17 wrote: Sat Nov 26, 2022 10:00 am In my code, there is a panel, let's name it noteBookPanel, this panel takes somehow a long time to show, during that time i want to show a loading panel for the user. But this panel is added to wxNoteBook and i will be making a lot of noteBookPanel and show them using notebook. now there is a problem that i want to run a two threads, both of them will run after a mouse event, the first one will make a panel and add it to the notebook, the second one will keep checking if the panel the i make is ready, if it is not ready it will still show the loading panel.
Forget about that, you can't create new GUI elements in a secondary thread.

Do you know why the panel takes so long to show? What's does it contain?
Use the source, Luke!
Mamo_Grag17
Earned some good credits
Earned some good credits
Posts: 107
Joined: Thu Mar 31, 2022 7:45 pm
Location: Morocco

Re: show a loading panel while a panel is not ready yet

Post by Mamo_Grag17 »

doublemax wrote: Sat Nov 26, 2022 10:30 am ]Forget about that, you can't create new GUI elements in a secondary thread.

Do you know why the panel takes so long to show? What's does it contain?
Ok thank you, i didn't know that it is impossible.

It takes too long cause i need to get some informations in user pc, and also it uses curl so it depends on internet...

I don't know why in wxwidgets it is impossible to do what i wanted, cause there are a lot of applications that have loading panel while something isn't ready yet.
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: show a loading panel while a panel is not ready yet

Post by doublemax »

I didn't say it was impossible, i just said that you can't create the GUI elements in a secondary thread.

You can create the panel, just put a "loading" text onto it and display it. Then you start the thread that gathers the information from the internet. When the thread is done, you send this data to the main thread which replaces the "Loading" content on the panel with the new content.
Use the source, Luke!
Mamo_Grag17
Earned some good credits
Earned some good credits
Posts: 107
Joined: Thu Mar 31, 2022 7:45 pm
Location: Morocco

Re: show a loading panel while a panel is not ready yet

Post by Mamo_Grag17 »

doublemax wrote: Sat Nov 26, 2022 1:34 pm I didn't say it was impossible, i just said that you can't create the GUI elements in a secondary thread.

You can create the panel, just put a "loading" text onto it and display it. Then you start the thread that gathers the information from the internet. When the thread is done, you send this data to the main thread which replaces the "Loading" content on the panel with the new content.
the structure is somehow not the one you will make like that, this is the code:

Code: Select all

noteBookPanel::noteBookPanel(wxWindow * parent) : wxPanel(parent)
{


  panelSizer = new wxGridSizer(3,3,3,3);
  applicationOne = new applicationPanel(this,wxBORDER_THEME);
  applicationTwo = new applicationPanel(this,wxBORDER_THEME);
  applicationThree = new applicationPanel(this,wxBORDER_THEME);
  applicationFour = new applicationPanel(this,wxBORDER_THEME);
  applicationFive= new applicationPanel(this,wxBORDER_THEME);
  applicationSex = new applicationPanel(this,wxBORDER_THEME);
  applicationSeven = new applicationPanel(this,wxBORDER_THEME);
  applicationEight = new applicationPanel(this,wxBORDER_THEME);
  applicationNine = new applicationPanel(this,wxBORDER_THEME);

  panelSizer->Add(applicationOne,1,wxEXPAND,wxALL);
  panelSizer->Add(applicationTwo,1,wxEXPAND,wxALL);
  panelSizer->Add(applicationThree,1,wxEXPAND,wxALL);
  panelSizer->Add(applicationFour,1,wxEXPAND,wxALL);
  panelSizer->Add(applicationFive,1,wxEXPAND,wxALL);
  panelSizer->Add(applicationSex,1,wxEXPAND,wxALL);
  panelSizer->Add(applicationSeven,1,wxEXPAND,wxALL);
  panelSizer->Add(applicationEight,1,wxEXPAND,wxALL);
  panelSizer->Add(applicationNine,1,wxEXPAND,wxALL);

}
as you can see i call applicationPanel 9 times, and i just don't know how to make all that stuff working
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: show a loading panel while a panel is not ready yet

Post by doublemax »

As the new wxWebRequest class works asynchronously, you might be able to do this without threads.

I hacked this little header-only panel together that displays just a "loading" wxStaticText, then loads a cat image from the internet and when done replaces the wxStaticText with a wxStaticBitmap. Maybe you can use this as inspiration for your own code:
Attachments
cat_panel.h
(1.98 KiB) Downloaded 140 times
Use the source, Luke!
Mamo_Grag17
Earned some good credits
Earned some good credits
Posts: 107
Joined: Thu Mar 31, 2022 7:45 pm
Location: Morocco

Re: show a loading panel while a panel is not ready yet

Post by Mamo_Grag17 »

doublemax wrote: Sat Nov 26, 2022 11:09 pm As the new wxWebRequest class works asynchronously, you might be able to do this without threads.

I hacked this little header-only panel together that displays just a "loading" wxStaticText, then loads a cat image from the internet and when done replaces the wxStaticText with a wxStaticBitmap. Maybe you can use this as inspiration for your own code:
I tried to inspire the event from it, i used threads but i don't know why it doesn't work:

Code: Select all

noteBook::noteBook(wxWindow *parent) : wxNotebook(parent,wxID_ANY)
{
  loadingPanel = new wxPanel(this);
  loadingAnimation = new wxAnimationCtrl(loadingPanel,-1,wxAnimation("/home/mamograg/Pictures/ZKZx.gif",wxANIMATION_TYPE_GIF));
  loadingAnimation->Play();

  this->AddPage(loadingPanel,"",true);
  
  //this event is not doesn't execute
  Bind(wxEVT_THREAD,[=](wxThreadEvent& evt)
  {
  noteBookPanel * panel = new noteBookPanel(this);
  this->AddPage(panel,"",true);
  });

}
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: show a loading panel while a panel is not ready yet

Post by doublemax »

Code: Select all

Bind(wxEVT_THREAD,[=](wxThreadEvent& evt)
Who or what is supposed to emit this event? wxAnimationCtrl surely doesn't.

What did you expect to happen?
Use the source, Luke!
Mamo_Grag17
Earned some good credits
Earned some good credits
Posts: 107
Joined: Thu Mar 31, 2022 7:45 pm
Location: Morocco

Re: show a loading panel while a panel is not ready yet

Post by Mamo_Grag17 »

doublemax wrote: Sat Dec 03, 2022 3:13 pm

Code: Select all

Bind(wxEVT_THREAD,[=](wxThreadEvent& evt)
Who or what is supposed to emit this event? wxAnimationCtrl surely doesn't.

What did you expect to happen?
I expected it to show wxanimationCtrl, and in tge same time it will make the panel and when it is ready it will change the wxAnimation panel with the new one.
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: show a loading panel while a panel is not ready yet

Post by doublemax »

Do you have a thread that sends this event? If yes, where does it send it to?
Use the source, Luke!
Mamo_Grag17
Earned some good credits
Earned some good credits
Posts: 107
Joined: Thu Mar 31, 2022 7:45 pm
Location: Morocco

Re: show a loading panel while a panel is not ready yet

Post by Mamo_Grag17 »

doublemax wrote: Sat Dec 03, 2022 6:04 pm Do you have a thread that sends this event? If yes, where does it send it to?
i tried another method that is making an std::thread, then run a function that will do the online things, but the same problem, the application waits until the online panel job is done then it shows, not what like i expected.

Code: Select all

noteBook::noteBook(wxWindow *parent) : wxNotebook(parent,wxID_ANY)
{
  loadingPanel = new wxPanel(this);
  loadingAnimation = new wxAnimationCtrl(loadingPanel,-1,wxAnimation("/home/mamograg/Pictures/ZKZx.gif",wxANIMATION_TYPE_GIF));
  loadingAnimation->Play();
  this->AddPage(loadingPanel,"",true);
  
  const auto f = [this](){
    noteBookPanel * panel = new noteBookPanel(this);
    this->AddPage(panel,"",true);
    
  };

  std::thread thread(f);
  thread.join();  
  
}
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: show a loading panel while a panel is not ready yet

Post by doublemax »

The examples you're showing are pointless, there is nothing that takes time and needs to be in a separate thread. If you're loading something from the internet, use my example code using wxWebrequest.
Use the source, Luke!
Post Reply