I need modify a property in other window

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
mxoliveira73
Experienced Solver
Experienced Solver
Posts: 56
Joined: Sun May 05, 2019 7:12 am

I need modify a property in other window

Post by mxoliveira73 » Sun May 19, 2019 2:25 pm

In file my.cpp one variable is set;
In file main.cpp there are class wxwidgets, frame, wxStaticText etc...

When a variable in my.cpp change, change label in wxStatictext(in main.cpp)

Problem: There are not event happen in main.cpp. The order is from my.cpp;
Attachments
mudar.jpg
mudar.jpg (22.66 KiB) Viewed 471 times

Kvaz1r
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 212
Joined: Tue Jun 07, 2016 1:07 pm

Re: I need modify a property in other window

Post by Kvaz1r » Sun May 19, 2019 2:34 pm

Can you describe what are you trying to achieve?
It's seems to me as The XY Problem.

mxoliveira73
Experienced Solver
Experienced Solver
Posts: 56
Joined: Sun May 05, 2019 7:12 am

Re: I need modify a property in other window

Post by mxoliveira73 » Sun May 19, 2019 3:44 pm

I'm creating an simple audio editor.
There is a scrolledWindow in mainFrame.
When the audio is in, for example, 20 seconds, it's necessary load other part of wxScrolledWindow.

Then, i create a variable; when audio is in 20 seconds, this varible it will be: int a = 15;
then, ScrolledWindow1->Scroll(a,0); and next part of scroleldWindow is load;
How yoy see, there is not event happens;
Attachments
scroll.jpg

alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 317
Joined: Tue Oct 18, 2016 2:31 pm

Re: I need modify a property in other window

Post by alys666 » Sun May 19, 2019 4:06 pm

to change label if string has been changed, you must some how call the code label.SetText(...) again.
why the label has to change it's text, if you did not call SetText again?

there are 3 ways to do it
1. naive - change text and directly call label.SetText(text);
2. via events synchronously.
3. via events asynchronously.
ubuntu 16.04, wxWidgets 3.0.4

mxoliveira73
Experienced Solver
Experienced Solver
Posts: 56
Joined: Sun May 05, 2019 7:12 am

Re: I need modify a property in other window

Post by mxoliveira73 » Sun May 19, 2019 4:27 pm

This is my problem: I need change a property of a wx/class. But, the key , the order to change it's not a event Wxwidgets. It will come from somewhere( int in other file .cpp). I could do that:

StaticText1->Setlabel(int a);// out of event function, but it's generate a error: StaticText1 it's not declarated in this scope; it can declarated only in a
function event, but there is not event happens in Wxwidgets class, but there are other things happens in other parts of
software... The change in label it'ss only a example;

mxoliveira73
Experienced Solver
Experienced Solver
Posts: 56
Joined: Sun May 05, 2019 7:12 am

Re: I need modify a property in other window

Post by mxoliveira73 » Sun May 19, 2019 4:37 pm

My event that change variable it's not a WxWidgets event

alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 317
Joined: Tue Oct 18, 2016 2:31 pm

Re: I need modify a property in other window

Post by alys666 » Sun May 19, 2019 5:12 pm

you must use a synchronous events mechanism as addition to wxWidgets events.
in my code i have my implementation of it, i used for years, and it is not connected with wxWidgets.
it depends on my original list templates, i also used for years :)
because a lot of work i did, was for baremetal designs, where std::lists, boost or something was and is too excessive.
idea of this tech is simple:
you must call at some code point a method Raise(event) of an "event_source". event source hides a list of event handlers, and just calls their formal method onEvent(...).
to handle such an events you must inherit your class from ListenerBase, redefine onEvent method, and register this class on eventSource at programm start.

Code: Select all

	
	class Event{
		int 		_kind=0; //event kind
		long 	_int0=0; //event data - if any
		const wxString &_text; //associated text - if any
	public:
		Event(int fkind, long fval, const wxString& ftext);
	public:
		int kind() const {return _kind;}
		int int0() const {return _int0;}
		const wxString & text() const {return _text;}
	};

	//derrive original listeners from this class
	class ListenerBase{
	public:
		ListenerBase(){};
		virtual ~ListenerBase(){};
		virtual void onBusEvent(Bus::Event  &){}; //redefine this method in derrived class
	};

	//###########################
	//this proxy object is just a reference to real object, inserted in different double linked lists
	class ListenerProxy{
	public:
		ListenerProxy *_next=nullptr,*_prev=nullptr; 
		ListenerBase* _object=nullptr; //referenced object
	public:
		ListenerProxy(ListenerBase* fo):_object(fo){};
		virtual ~ListenerProxy(){};
		ListenerBase *object(){return _object;}
	};

	//###########################
	//Synchronous events
	//double linked list of listeners,
	class EventSlot: private Helper::SimpleDoubleList<ListenerProxy> {
	public:
		void addListener(ListenerBase *fe); //add listener to listen this slot
		void removeListener(ListenerBase *fe); //remove listener from listeners list
		void raise(Bus::Event &fe); //raise an event - it will poll listeners and call their onBusEvent(...)
		EventSlot();
		~EventSlot();
	};
}
but you cant implement it because I use original Helper::SimpleDoubleList
it could be reimplemented on std::list, but i cannot do it just now.

ps. i decided to reimplement it via std:lists, just for fun and make it templated. so wait a bit pls.
Last edited by alys666 on Sun May 19, 2019 5:19 pm, edited 1 time in total.
ubuntu 16.04, wxWidgets 3.0.4

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

Re: I need modify a property in other window

Post by doublemax » Sun May 19, 2019 5:17 pm

There is no event that happens when you change a variable somewhere. And modifying a variable of another class - or even a global variable - directly, is not a good idea.

In the class where the variable is defined, you should add a method to set that variable. And in that method you should also change the wxStaticText. This makes sure the text always displays the value of the variable.
Use the source, Luke!

Kvaz1r
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 212
Joined: Tue Jun 07, 2016 1:07 pm

Re: I need modify a property in other window

Post by Kvaz1r » Sun May 19, 2019 8:31 pm

mxoliveira73 wrote:
Sun May 19, 2019 3:44 pm
I'm creating an simple audio editor.
There is a scrolledWindow in mainFrame.
When the audio is in, for example, 20 seconds, it's necessary load other part of wxScrolledWindow.
It's still unclear for me.
Do you need update ScrollWindow when the data were updated (from somewhere, the data don't depend of ScrollWindow) or opposite - send message (to somewhere) that something happened?
Do you need message passing in both directions or in only one? Do this parts equal/independent or they have parent-child connection? (i.e. how relates ScrollWindow and other part?)

alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 317
Joined: Tue Oct 18, 2016 2:31 pm

Re: I need modify a property in other window

Post by alys666 » Sun May 19, 2019 9:49 pm

Code: Select all

#include <list>

//template class for sync events dispatching
template <class T>
class ListenerBaseTemplate{
public:
	ListenerBaseTemplate(){};
	virtual ~ListenerBaseTemplate(){};
	virtual void onEvent(const T &){}; //this method must be redefined in actual class
};

//template class for async event source
template <class T>
class EventSlotTemplate {
	typedef ListenerBaseTemplate<T> __Listener;
	std::list<void*> _list; //store pointers in void* list
public:
	//add listener to listen this slot
	void addListener(__Listener *fe){
		if(fe==nullptr) return;
		_list.push_back(fe);//first added, gets an event first
	}

	//remove listener from listening list
	void removeListener(__Listener *fe){
		_list.remove(fe);
	}

	void raise(const T &fe){
		//poll all  registered listeners and give them an event
		for (auto li = _list.begin(); li != _list.end(); ++li){
			static_cast<__Listener*>(*li)->onEvent(fe);
		}
	}

	EventSlotTemplate(){};
	~EventSlotTemplate(){_list.clear();};
};
test

Code: Select all


//declare an event with string data
class MyEvent{
public:	
	wxString _text;
	MyEvent(const wxString &fe):_text(fe){}
};

//declare event source for MyEvent events
EventSlotTemplate<MyEvent> _Bus;

//decalare listener class reacting on MyEvent
class testListener:public ListenerBaseTemplate<MyEvent>{
public:	
	void onEvent(const MyEvent & fe)override{
		//do something useful on event
	};
};

//let test it
void test(){
	testListener *ll = new testListener(); //create new listener
	_Bus.addListener(ll); //add it to _Bus
	_Bus.raise(MyEvent("this is text")); //raise an event on _Slot
	_Bus.removeListener(ll);
	delete ll;
}
write your event class with fields you need to give to different listeners.
like MyEvent here.

define somewhere in your kernel files EventSlotTemplate<YourEvent> MyBus;

how to use in your code - inherit the control class, where you included your button from
ListenerBaseTemplate<YourEvent>, overide method:
void onEvent(const YourEvent & event ){
_label->SetText(event._text);
}
in constructor of this control, write
MyBus.addListener(this);
---
when after changing some __string text write:
MyBus.raise(YourEvent(__string));

ask questions... i'm sure you cannot understand a lot here :)
ubuntu 16.04, wxWidgets 3.0.4

Post Reply