Bonjour
wxWidgets 3.1
My wxFrame : "PhotosToUpload" copies files from directory "srcDir" to directory "destDir"
Works fine.
Now more informative, "PhotosToUpload" call my wxFrame : "FilesToStartMoveAndShown" wich shall do two things
- start the copy of files in "PhotosToUpload" with a wxButton "start" : OK, works
- show a wxListCtrl : "list0", wich should add and show a new item with the name of the file moved, each time a file is moved :
problem : the names of the files moved is shown all together after all the files are moved and not after each file is moved
I use two method :
- in "PhotosToUpload" : filesToStartMoveAndShown->getList0()->InsertItem(index, "name of the current files beiing moved);
- defining a event with wxDEFINE_EVENT(FROM_UPLOAD_TO_AFFICHE_MOVE, wxCommandEvent), with wxPostEvent in "PhotosToUpload" and
the handler in "FilesToStartMoveAndShown"
NB : I want one only class "FilesToStartMoveAndShown", for many class like "PhotosToUpload", example "PhotoToDownload"...
I read much documentation, not really clear.
Should I use wxThread (as in sample thread GUI), wxMutex, other ?
What is the simplest possible ?
Merci
How to make an event execute immediately ? Topic is solved
Re: How to make an event execute immediately ?
Showing some code would have been helpful.
Without knowing more about the "bigger picture", try this:
Without knowing more about the "bigger picture", try this:
Code: Select all
getList0()->InsertItem(...)
getList0()->Refresh(); // request redraw
::wxYield(); // trigger processing events
Use the source, Luke!
Re: How to make an event execute immediately ?
Only the OS dispatches the event to its handler. This means that you can post an event but you don't know when it will be "back" to your app.
The solution doublemax showed may help a bit, because wxYield will give the OS some time and then continue with the next instruction in your code.
Anyhow updating the GUI while some job is doing is the typical case for a working thread (your PhotosToUpload) that sends events to the main GUI thread when it needs to be updated (new item in a list control).
The solution doublemax showed may help a bit, because wxYield will give the OS some time and then continue with the next instruction in your code.
Anyhow updating the GUI while some job is doing is the typical case for a working thread (your PhotosToUpload) that sends events to the main GUI thread when it needs to be updated (new item in a list control).
Re: How to make an event execute immediately ?
Merci.
"The solution doublemax showed" helps.
My application is builded with several modules.
The modules are independent, more or less, each other.
Example : a module include several sub-modules, here "PhotosToUpload", "PhotoToDownload", etc. ; each of that sud-modules send infos to an uniq spcial sub-module which is a GUI, here "FilesToStartMoveAndShown".
There, I am lost.
What is the meaning of the main GUI thread ? It is a wxThread class, wich is a kind of wrapper form my wxFrame "FilesToStartMoveAndShown" ?
If I refer to the example in "wxThread Class Reference" and for my understanding, it is OK to replace the names
MyFrame : FilesToStartMoveAndShown
MyThread : CommonSpecialGuiModule
Then in "OnThreadUpdate(wxThreadEvent&)" I add something like
m_pHandler->getList0()->InsertItem(index, "File moved");
In "PhotosToUpload" I add
CommonSpecialGuiModule *CommonSpecialGuiModule = new CommonSpecialGuiModule(FilesToStartMoveAndShown *handler);
FilesToStartMoveAndShown-> DoStartThread(); (in "PhotosToUpload" instead to be called by a wxMenu ?)
And I use the classical wxPostEvent to send the wxEVT_COMMAND_MYTHREAD_UPDATE event to update the "list0", what is immediately done, safely and robustly ???
That is an correct approach ? Shall I go further in that direction ?
"The solution doublemax showed" helps.
My application is builded with several modules.
The modules are independent, more or less, each other.
Example : a module include several sub-modules, here "PhotosToUpload", "PhotoToDownload", etc. ; each of that sud-modules send infos to an uniq spcial sub-module which is a GUI, here "FilesToStartMoveAndShown".
There, I am lost.
What is the meaning of the main GUI thread ? It is a wxThread class, wich is a kind of wrapper form my wxFrame "FilesToStartMoveAndShown" ?
If I refer to the example in "wxThread Class Reference" and for my understanding, it is OK to replace the names
MyFrame : FilesToStartMoveAndShown
MyThread : CommonSpecialGuiModule
Then in "OnThreadUpdate(wxThreadEvent&)" I add something like
m_pHandler->getList0()->InsertItem(index, "File moved");
In "PhotosToUpload" I add
CommonSpecialGuiModule *CommonSpecialGuiModule = new CommonSpecialGuiModule(FilesToStartMoveAndShown *handler);
FilesToStartMoveAndShown-> DoStartThread(); (in "PhotosToUpload" instead to be called by a wxMenu ?)
And I use the classical wxPostEvent to send the wxEVT_COMMAND_MYTHREAD_UPDATE event to update the "list0", what is immediately done, safely and robustly ???
That is an correct approach ? Shall I go further in that direction ?
Re: How to make an event execute immediately ?
The Graphic User Interface (GUI) runs in the "main thread", the one where your app executes. It could run in a secondary thread, but then the OS will get confused, the events will go "somewhere", and you app would stop responding to user actions.
An app consists on several tasks to be done. Some may start due to a timer, some due to common OS events (e.g. paint, resize, etc) and normally most due to user clicking a menu, button, etc.
When a task must be done (i.e. the proper handler is called) and only the main thread is active, the rest of tasks wait until this task is over. "rest of tasks" includes GUI update and all other stuff. Here is where wxYield helps: it allows pending events to be handled, at the price of perhaps blocking user action or delaying old actions.
If a taks is quickly done (say a few milliseconds) then it seems as if everything happened "at once": task is done, GUI is updated, user actions are accepted inmediately. No multi-thread is needed.
But if not, then everything is blocked. Think of a slow device (DVD, hard-disk, remote server, etc) being used: user clicks on "cancel" but nothing happens, not even the button changes its color. A case for using a dedicated thread for that task.
It's up to you to decide if your app needs multithreading or not.
A good advice: all GUI action (generate, update, etc) must be done only in the main thread.
An app consists on several tasks to be done. Some may start due to a timer, some due to common OS events (e.g. paint, resize, etc) and normally most due to user clicking a menu, button, etc.
When a task must be done (i.e. the proper handler is called) and only the main thread is active, the rest of tasks wait until this task is over. "rest of tasks" includes GUI update and all other stuff. Here is where wxYield helps: it allows pending events to be handled, at the price of perhaps blocking user action or delaying old actions.
If a taks is quickly done (say a few milliseconds) then it seems as if everything happened "at once": task is done, GUI is updated, user actions are accepted inmediately. No multi-thread is needed.
But if not, then everything is blocked. Think of a slow device (DVD, hard-disk, remote server, etc) being used: user clicks on "cancel" but nothing happens, not even the button changes its color. A case for using a dedicated thread for that task.
It's up to you to decide if your app needs multithreading or not.
A good advice: all GUI action (generate, update, etc) must be done only in the main thread.
Re: How to make an event execute immediately ?
In addition to Manolo' reply:
You can post an event from the secondary thread to the "main" one in order to update the GUI. It can be either user-declared event or the wxThreadEvent. For an example check the thread sample and event sample.
You can post an event from the secondary thread to the "main" one in order to update the GUI. It can be either user-declared event or the wxThreadEvent. For an example check the thread sample and event sample.
Re: How to make an event execute immediately ?
Merci.
Very interesting for me : I understand that I understanded nothing how to works an application...
Some silly questions.
First, what is the "main thread" :
When I create MyApp (class MyApp : public wxApp), the "main tread" is created. All is in "main thread", unless I create secondary thread (with wxThread) ? Right ?
Next, what is "The Graphic User Interface (GUI)" : there is only one GUI for my Application, if mon-thread ? My I say that it is a mecanisme hided, wich cover all the interactions with the user (mouse/key clicks, etc ) in the existing frames in the application ?
I read several times your posts and the official documentation (http://docs.wxwidgets.org/3.1/overview_thread.html) :
"To implement non-blocking operations without using multiple threads you have two possible implementation choices:
"use wxIdleEvent (e.g. to perform a long calculation while updating a progress dialog)
"do everything at once but call wxWindow::Update() or wxApp::YieldFor(wxEVT_CATEGORY_UI) periodically to update the screen."
I believe I forget the idea of multi-threading : my application has - a priori - no blocking operations.
It is better to use wxApp::YieldFor(wxEVT_CATEGORY_UI) or wxApp::YieldFor(wxEVT_CATEGORY_ALL) or only wxApp::Yeld() ?
Sorry for my poor english...
Very interesting for me : I understand that I understanded nothing how to works an application...
Some silly questions.
First, what is the "main thread" :
When I create MyApp (class MyApp : public wxApp), the "main tread" is created. All is in "main thread", unless I create secondary thread (with wxThread) ? Right ?
Next, what is "The Graphic User Interface (GUI)" : there is only one GUI for my Application, if mon-thread ? My I say that it is a mecanisme hided, wich cover all the interactions with the user (mouse/key clicks, etc ) in the existing frames in the application ?
I read several times your posts and the official documentation (http://docs.wxwidgets.org/3.1/overview_thread.html) :
"To implement non-blocking operations without using multiple threads you have two possible implementation choices:
"use wxIdleEvent (e.g. to perform a long calculation while updating a progress dialog)
"do everything at once but call wxWindow::Update() or wxApp::YieldFor(wxEVT_CATEGORY_UI) periodically to update the screen."
I believe I forget the idea of multi-threading : my application has - a priori - no blocking operations.
It is better to use wxApp::YieldFor(wxEVT_CATEGORY_UI) or wxApp::YieldFor(wxEVT_CATEGORY_ALL) or only wxApp::Yeld() ?
Sorry for my poor english...
Re: How to make an event execute immediately ?
mybofy wrote: Merci.
Very interesting for me : I understand that I understanded nothing how to works an application...
There is no such thing as a silly question - only a silly answer....mybofy wrote: Some silly questions.
First, what is the "main thread" :
When I create MyApp (class MyApp : public wxApp), the "main tread" is created. All is in "main thread", unless I create secondary thread (with wxThread) ? Right ?
But to answer the first question - yes, that is correct.
When you create an application it automatically creates a "main" thread for you by the underlying OS.
Then this thread creates a main window and all other GUI controls - list boxes, buttons, etc. And then the user of you application will interact with all those controls using mouse/keyboard or on some platforms with hands/fingers.
I already touched the answer to this question - GUI or Graphical User Interface is defined as windows with which user is operating the data on the screen, being it a button, grid or a simple list box or even a main frame which holds all those controls the way you designed it.mybofy wrote: Next, what is "The Graphic User Interface (GUI)" : there is only one GUI for my Application, if mon-thread ? My I say that it is a mecanisme hided, wich cover all the interactions with the user (mouse/key clicks, etc ) in the existing frames in the application ?
Or simply put - it is a graphical presentation to the user of what the program will do and can do.
As you can see you answer is not really correct.
As doublemax said - just use "::wxYield();".mybofy wrote: I read several times your posts and the official documentation (http://docs.wxwidgets.org/3.1/overview_thread.html) :
"To implement non-blocking operations without using multiple threads you have two possible implementation choices:
"use wxIdleEvent (e.g. to perform a long calculation while updating a progress dialog)
"do everything at once but call wxWindow::Update() or wxApp::YieldFor(wxEVT_CATEGORY_UI) periodically to update the screen."
I believe I forget the idea of multi-threading : my application has - a priori - no blocking operations.
It is better to use wxApp::YieldFor(wxEVT_CATEGORY_UI) or wxApp::YieldFor(wxEVT_CATEGORY_ALL) or only wxApp::Yeld() ?
Sorry for my poor english...
You probably know that application will create a main thread for you and this main thread will create a main window with all controls you put in.
Now all those controls are interacting with each other and with the user thru the events - you click the mouse on the button and the program sends an appropriate event to the system for processing.You press the key on the keyboard - the same thing. When you program will need to draw something - it also sends an event to the operating system for processing.
Now in you program you can intercept those events by using an event handler. If the execution time for the handler is significantly large - more than couple of minutes - it is a good idea to tell the user "Hey I'm working!!! Please wait..."
This can be achieved thru the wxProgressDialog (check the dialog sample) or just use busy cursor.
However if the program takes just couple of minutes to run - it is easier to use doublemax' code. What wxYield() does is following - you click on the button and you handler started working, but it work is continuous - meaning it will not return until finished. Which means you as a user will not be able to move the mouse, perform any drawing, type anything, etc. But if you put wxYield() in the handler - it will direct the handler to hold for a quick second and let the OS process any other possible events that occurred and then continue processing.
Now it is up to you to decide how to design you application.
If you have more questions - don't hesitate to ask.
Thank you.