Refresh panels in wxnotebook

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
marcusbarnet
Experienced Solver
Experienced Solver
Posts: 71
Joined: Sat Jul 27, 2019 3:45 pm

Refresh panels in wxnotebook

Post by marcusbarnet » Sun Oct 27, 2019 5:59 pm

What is the best method to refresh panels in wxnotebook?
My application flow let the user navigate from panel 1 to panel 3, at the end of the procedure, the user can load a new operation starting from panel 1.

I would like to reload the first panel by clearing all the forms and all the values previously changed by the user.
What is the best method?
I use changeselection() to navigate trough the panels, but this doesn't reset the panels (obviously).

Code: Select all

//isola02App.cpp
wxIMPLEMENT_APP(Isola02App);

bool Isola02App::OnInit()
{
    Isola02Frame* frame = new Isola02Frame(L"Isola02Frame");
    pointer = frame;
    frame->Show(true);
    wxInitAllImageHandlers();
    m_timer.Bind(wxEVT_TIMER, &Isola02App::reset, this);
    return true;
}

int Isola02App::FilterEvent(wxEvent &event)
{
  if(event.GetEventType()==wxEVT_CHAR || event.GetEventType()==wxEVT_LEFT_DOWN ) {

    m_timer.StartOnce(100*60*60);
    printf("hey\n");
  }
  return -1;
}

void Isola02App::reset(wxTimerEvent&){
    pointer->ShowPage(1);
    printf("reset\n");
}

//isola02Main.cpp

Isola02Frame::Isola02Frame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
     wxInitAllImageHandlers();
    // Create a top-level panel to hold all the contents of the frame
    //wxPanel* panel = new wxPanel(firstpanel, wxID_ANY);
   // firstpanel* panel = new firstpanel(this, wxID_ANY);
    // Create the wxNotebook widget
    notebook = new wxSimplebook(this, wxID_ANY);

    firstpanel *first = new firstpanel(notebook, this, wxID_ANY);
    notebook->AddPage(first, L"first panel");

    secondpanel *second = new secondpanel(notebook, this, wxID_ANY);
    notebook->AddPage(second, L"second panel");

    notebook->SetSelection(0);

    ShowFullScreen(true);

}

void Isola02Frame::ShowPage(int page)
{
  notebook->ChangeSelection(page);
}

//secondpanel.cpp

BEGIN_EVENT_TABLE(secondpanel,wxPanel)
	//(*EventTable(secondpanel)
	//*)
END_EVENT_TABLE()

secondpanel::secondpanel(wxWindow* parent, Isola02Frame *mainFrame, wxWindowID id,const wxPoint& pos,const wxSize& size)
{
	pointer = mainFrame;

	//(*Initialize(secondpanel)
	Create(parent, wxID_ANY, wxPoint(-1,-1), wxSize(1323,827), wxTAB_TRAVERSAL, _T("wxID_ANY"));
	SetMaxSize(wxSize(-1,-1));
	SetBackgroundColour(wxColour(176,253,203));
	selezione_tipologia = new wxStaticText(this, ID_STATICTEXT1, _("Seleziona il tipo di conferimento"), wxPoint(384,32), wxSize(792,42), 0, _T("ID_STATICTEXT1"));
	wxFont selezione_tipologiaFont(26,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Sans"),wxFONTENCODING_DEFAULT);
	selezione_tipologia->SetFont(selezione_tipologiaFont);
	BitmapButton1 = new wxBitmapButton(this, ID_BITMAPBUTTON7, wxBitmap(wxImage(_T("/home/isola/Documents/Isola02/pics/remove-128.png"))), wxPoint(24,24), wxDefaultSize, wxBU_AUTODRAW|wxNO_BORDER, wxDefaultValidator, _T("ID_BITMAPBUTTON7"));

	Connect(ID_BITMAPBUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&secondpanel::OnplasticaClick);
	Connect(ID_BITMAPBUTTON2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&secondpanel::OnBitmapButton2Click);
	Connect(ID_BITMAPBUTTON7,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&secondpanel::OnBitmapButton1Click);
	//*)

}

secondpanel::~secondpanel()
{
	//(*Destroy(secondpanel)
	//*)
}

void secondpanel::OnBitmapButton1Click(wxCommandEvent& event)
{
    pointer->ShowPage(0);
}
I tried to do in this way:

Code: Select all

void secondpanel::OnBitmapButton1Click(wxCommandEvent& event)
{
    pointer->ShowPage(0);
 // pointer->notebook->Freeze();
 // pointer->notebook->Thaw();
    pointer->notebook->Update();
}
but it doesn't work, I also tried the refresh method with no success.

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

Re: Refresh panels in wxnotebook

Post by doublemax » Sun Oct 27, 2019 7:10 pm

There is no magic trick for this. You can either delete the panel and create a new one or have a dedicated method that resets every single control that could have changed. I would suggest the latter.
Use the source, Luke!

marcusbarnet
Experienced Solver
Experienced Solver
Posts: 71
Joined: Sat Jul 27, 2019 3:45 pm

Re: Refresh panels in wxnotebook

Post by marcusbarnet » Sun Oct 27, 2019 7:59 pm

what is the best solution to reset every single controls and every single variable?

All the panels are created in:

Code: Select all

//isola02Main.cpp

Isola02Frame::Isola02Frame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
     wxInitAllImageHandlers();
    // Create a top-level panel to hold all the contents of the frame
    //wxPanel* panel = new wxPanel(firstpanel, wxID_ANY);
   // firstpanel* panel = new firstpanel(this, wxID_ANY);
    // Create the wxNotebook widget
    notebook = new wxSimplebook(this, wxID_ANY);

    firstpanel *first = new firstpanel(notebook, this, wxID_ANY);
    notebook->AddPage(first, L"first panel");

    secondpanel *second = new secondpanel(notebook, this, wxID_ANY);
    notebook->AddPage(second, L"second panel");

    notebook->SetSelection(0);

    ShowFullScreen(true);

}
In every panel, I have a pointer to Isola02Frame:

Code: Select all

secondpanel::secondpanel(wxWindow* parent, Isola02Frame *mainFrame, wxWindowID id,const wxPoint& pos,const wxSize& size)
{
	pointer = mainFrame;
	...
}
so I can access to notebook, but I can't directly access to firstpanel pointer.
I was thinking to write a function:

Code: Select all

void Isola02Frame::panel_refresh(){
// rest all the controls
}
but I can't figure out how to access to the controls and variables

marcusbarnet
Experienced Solver
Experienced Solver
Posts: 71
Joined: Sat Jul 27, 2019 3:45 pm

Re: Refresh panels in wxnotebook

Post by marcusbarnet » Sun Oct 27, 2019 8:07 pm

I declared:

Code: Select all

firstpanel *first;
secondpanel *second;
as global in Isola02Main.cpp and then I specified a function in Isola02Frame.cpp:

Code: Select all

void Isola02Frame::panel_refresh(){
first->errore->Hide();
first->tessera->Clear();
}

//secondpanel.cpp

void secondpanel::OnBitmapButton1Click(wxCommandEvent& event)
{
    pointer->panel_refresh();
    pointer->ShowPage(0);
}
It seems to work, but I do not know if this is the solution you were talking about.

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

Re: Refresh panels in wxnotebook

Post by doublemax » Sun Oct 27, 2019 9:10 pm

Not exactly.

The main frame (Isola02Frame) should have 3 private member variables for the panels (you probably already have that).
And each of the panels should have a public Reset() (or how ever you want to call it) method.

Code: Select all

void firstPanel::Reset()
{
   // reset all controls of this panel here
   textctrl->Clear();
}
And in the main frame you have a method that performs the reset for all panels. This is the only method you call when you want to reset the GUI, etc. when the idle timeout triggers.

Code: Select all

void Isola02Frame::panel_refresh() {
  m_first->Reset();
  m_second->Reset();
  m_third->Reset();
  notebook->ShowPage(0);
}
Use the source, Luke!

marcusbarnet
Experienced Solver
Experienced Solver
Posts: 71
Joined: Sat Jul 27, 2019 3:45 pm

Re: Refresh panels in wxnotebook

Post by marcusbarnet » Sun Nov 03, 2019 7:26 pm

I'm having a problem and I can't understand why!
I was changing my code to fit your suggestions, I tried to compile it and I get this error:

Code: Select all

In file included from /home/isola/Documents/Isola02/Isola02Main.h:15:0,
                 from /home/isola/Documents/Isola02/Isola02Main.cpp:10:
/home/isola/Documents/Isola02/firstpanel.h:17:32: error: ‘Isola02Frame’ has not been declared
   firstpanel(wxWindow* parent, Isola02Frame *, wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
                                ^~~~~~~~~~~~
but I didn't change anything and the program was compiling fine before!
I tried to clean the environment and to rebuild it, but nothing changed.

Code: Select all

//firstpanel.h

#ifndef FIRSTPANEL_H
#define FIRSTPANEL_H
#include "Isola02Main.h"
#include <wx/timer.h>
#include "rePlay.h"

//(*Headers(firstpanel)
#include <wx/panel.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
//*)

class firstpanel: public wxPanel
{

	public:
		firstpanel(wxWindow* parent, Isola02Frame *, wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
		virtual ~firstpanel();
		void checkValue(wxCommandEvent& event);
		void check_cf(wxTimerEvent& event);
		rePlay *mp3_apertura_porta;
		rePlay* getPlayer() {
		    return mp3_apertura_porta;
		     }
        //(*Declarations(firstpanel)
        wxStaticText* assistenza;
        wxStaticText* errore;
        wxStaticText* first_panel;
        wxStaticText* identificazione;
        wxTextCtrl* tessera;
        //*)

	protected:
	    wxString surname = "Utente";   // now it should be "URSO"
        wxString name = "Utente";
        Isola02Frame *pointer;
        wxTimer tessera_timer;

        //(*Identifiers(firstpanel)
        static const long ID_STATICTEXT1;
        static const long ID_TEXTCTRL1;
        static const long ID_STATICTEXT2;
        static const long ID_STATICTEXT3;
        static const long ID_STATICTEXT4;
        //*)

	private:

		//(*Handlers(firstpanel)
		void OnButton1Click(wxCommandEvent& event);
		void OnTextCtrl1Text(wxCommandEvent& event);
		//*)

		DECLARE_EVENT_TABLE()
};

#endif

// Isola02Main.h

#ifndef ISOLA02MAIN_H
#define ISOLA02MAIN_H
#include <wx/simplebook.h>
#include <wx/timer.h>
#include <vlc/vlc.h>
#include "firstpanel.h"
#include "secondpanel.h"
#include "thirdpanel.h"
#include "Isola02Main.h"

//(*Headers(Isola02Frame)
#include <wx/frame.h>
//*)

class Isola02Frame : public wxFrame
{
public:
    Isola02Frame(const wxString& title);
    void ShowPage(int);
    wxSimplebook* notebook;
    void play_mp3(const char*);
    void stop_mp3();
    bool set_stop(bool);
    void panel_refresh();
    void set_cf(char *);

protected:
     libvlc_instance_t *inst;
     libvlc_media_player_t *mp;
     libvlc_media_t *m;
     bool stop = false;
};


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

Re: Refresh panels in wxnotebook

Post by doublemax » Sun Nov 03, 2019 7:43 pm

You might have a problem with a cyclic reference there (Isola02Main.h including firstpanel.h and firstpanel.h including Isola02Main.h)

In firstpanel.h, don't include Isola02Main.h, instead use a forward reference to Isola02Frame.

Code: Select all

class Isola02Frame;
class firstpanel: public wxPanel
{
 ...
Use the source, Luke!

marcusbarnet
Experienced Solver
Experienced Solver
Posts: 71
Joined: Sat Jul 27, 2019 3:45 pm

Re: Refresh panels in wxnotebook

Post by marcusbarnet » Sun Nov 03, 2019 9:45 pm

Your suggestion solved the problem, thank you!

Is that a problem which can occurs only with some compilers/systems or it is a common problem when you cross the headers?

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

Re: Refresh panels in wxnotebook

Post by doublemax » Sun Nov 03, 2019 9:56 pm

marcusbarnet wrote:
Sun Nov 03, 2019 9:45 pm
Is that a problem which can occurs only with some compilers/systems or it is a common problem when you cross the headers?
It's a common problem in C/C++ and using a forward reference is often a solution.
Use the source, Luke!

Post Reply