Making a music player in C++/GTK - c++

I would like to create a music player, but I'm working with robots.
My robot should play a series of action (speech, move, etc) and I need to be able to stop it at anytime (for security).
I'm working with C++ and GTK.
I have a PLAY button linked to the function play_playlist:
void play_playlist ()
{
std::deque<history_record>::iterator it = list_to_play_.begin();
while (!g_stop_ && it != list_to_play_.end())
{
play_action(it); // take time to execute (simulate using sleep 3sec)
it++;
}
}
And a STOP button linked to the function set_stop_to_false:
void set_stop_to_true()
{
g_stop_ = true;
}
When I click PLAY the GUI freezes and I'm not able to click on STOP.
How can I have my playlist running and be able to click on the GUI? (i.e. GUI should be responsive)
My best hope is a thread, but I'm not sure how to use it appropriately.

When I click PLAY the GUI freezes and I'm not able to click on STOP.
You need to build a multi-threaded application. Your interface freezes because your application is busy doing something else, so not only that events raised from GUI are not being processed but they are not even raised.
Your application should start a worker thread that will do its job in the background, the main thread can then communicate with this worker thread for example via shared memory.

Once you enter a callback like play_playlist, the GTK main loop can't process events until you exit that function, which freezes the user interface. As play_action takes seconds to run, you only have 2 choices:
split play_playlist execution in several smaller steps, and use a
state machine to execute each step one after the other using a
callback triggered by g_idle_add. Here's an example of this
technique for lazy loading.
the other solution is to run your blocking play_action in a thread. Give a look at GThread. You start your thread when you press PLAY and stop it when you press STOP. However, you can't manipulate the user interface from a thread, GTK is not thread safe. Every GTK action should be processed from the main thread.

Related

Qt executes an event before another event finishes its execution

I'm working on a project, which is a C++/Qt desktop application. In this application, I've identified a certain problem related to the execution of interface events.
For example, in this application, the mousePressEvent delegates a certain operation to the program, and this operation can be slow sometimes, so if the user presses the mouse button before this operation ends, the program begins to execute another operation before the previous one finishes.
Does anyone ever have this same issue with Qt?
Thank you.

How to Run an event while another event is running in wxWidgets GUI?

I created one GUI having two buttons. one is start button and the other is stop button. when start is pressed the program will execute in the background and the gui will freeze. I couldn't control the window anymore. even a mouse click is not responding. the stop button is for stopping the program. since the window is not responding as it is running the program i cant press stop. what is the possible solution? .please help
A thread is sort of a subprogram inside your program. When the application starts it runs in the main thread. You can create many other threads; all of them (the main one included) share the application memory space (for example, same global vars in scope).
There are two kind of threads: "detached" and "joinable". detached threads delete themselves when they finish, think of them as "fire and forget". Conversely, joinable threads are deleted by yourself, only after they have completed their job.
In wxWidgets all GUI is executed in the main thread. Calling a GUI function from another thread is a nightmare, don't do it.
Your case is a typical situation. The "start" button launches a thread to do some job. If you want to cancel this job you push the "stop" button.
How to instruct the thread to cancel its job?
While you can use wxCondition, you can also set a flag on your own. The working thread reads at some moment this flag (it's not automagic, you must code it) and stops or continue depending on its value. Don't forget to use a wxMutex before accesing the flag to protect it from another thread changing it at the same time.
Also, threads can post messages to the main thread event-loop. This way you can tell the main thread that your worker thread has finished its job.
Threads require more attention when you're coding them. You must avoid some situations such as:
"dead lock": two threads wait one for each other, none finishes.
"race condition": several threads try to change a shared value at the same
time.
More on wxWidgets docs and thread sample.
Finally, C++11 has std::thread and other related friends (mutexes, semaphores, etc). It's your choice to use it instead of wxWidgets classes.

Disabling control variable while worker thread is finishing MFC

I am working on a dialog-based MFC Application using Visual Studio 2015. Basically my problem is that I have a button that will start a worker thread after the user has chosen the necessary inputs (.csv files that will be parsed and put into different vectors). To avoid complications, I decided that the user will not be able to press this button or the input buttons until after the calculation done by the worker thread has finished. I tried the WaitforSingleObject options but defeats the purpose of keeping the main thread or the MFC Application running while waiting for the worker thread to finish. Is there any other workaround around this problem? I appreciate any help.
Your worker thread could post a completion message back to your UI thread. Your UI thread wouldn't need a special message loop in that case, instead your window procedure would then reenable the buttons when it receives that message.
You could use the MsgWaitForMultipleObjects function:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684242(v=vs.85).aspx
ATL uses it in AtlWaitWithMessageLoop(https://msdn.microsoft.com/en-us/library/26hwk2bx.aspx).

How to stop a function which is still computing with button stop?

I've an application visual c++ written using vs2010,
I have two buttons: "start" and "stop",the first one calls a function that takes a lot of time to process, so in a certain moment I'd like to stop the computation pressing stop button. But in my application the button start seems still clicked (I think it's waiting for the return of the function) and all the other buttons appear to be disabled. Even if I had a wonderful stop function, I could not active because I'm not able to click on button stop. Solutions,ideas,using threads,easy example? Thanks.
You need to run your calculations in another thread. Otherwise your gui freezes until your calculations are done (because only one thing can be done at the moment).
If you are using some modern compiler look at std::thread.
other solutions are boost threads or even microsoft threads.
If your computation is a loop, it may be quite easy to check at each iteration if your User wants to stop the computation.
In the computation thread:
while(compute){
// one loop of computation
}
While your GUI thread can set computationto false through your stop button.
I hope it helps
Note: In c++ as in java Swing etc.., the GUI has it's own thread (not really visible to the developer) and you should never do heavy tasks in it. For instance, every callbacks for buttons should be as small as possible to keep your GUI responsive. This thread's job is just to drive your application.
Button 1 -> onClick =
{
start thread -> { do stuff here }
}
BUtton 2 -> onClick =
{
close thread
}
Be careful when forcibly closing a thread because you can leak memory !
http://msdn.microsoft.com/it-it/library/system.componentmodel.backgroundworker%28v=vs.110%29.aspx
BackgroundWorker is perfect for this use!
First you need to imports the namespace
using System.Threading;
then use the following code :
Thread T=new Thread(Your Code Goes method name);
your method name()
{
// your code goes here
}
T.Start();
then
T.Abort();

Sleep() in Win32 makes program unresponsive

Basically exactly what the title says. I would like to update the text that a button contains every 1 second when the user presses that particular button. I have noted that when the program doesn't have focus it works alright and the text refreshes correctly but when I am hovering over the program or when I am trying to click on it's menu Windows inform me that the program is unresponsive and asks me if I want it terminated. When the loop finishes the program returns to its normal state. Also any action I might have done (like moving it around or closing it) while it was Sleep()-ing is executed after the loop. Here is a bit of code:
case ID_BUTTON_START:
// Code executed when pressing Start Button.
char startButtonText[30]; // Storing next loop text
for (int i=5; i>0; i--)
{
sprintf(startButtonText, "Starting in ... %d", i);
SendMessage(hwndButtonStart, WM_SETTEXT, 0, (LPARAM)(startButtonText));
Sleep(1000);
}
Is this normal? If not what's causing this?
The WndProc does not process messages asynchronously within an application which means all messages are expected to be handled quickly and a return value delivered immediately. You must not Sleep in the UI thread since it will block other UI events from being processed. Any heavy work or synchronous requests/jobs which are likely to take a long time should be performed in worker threads. There are at least three viable options:
Create a new (worker thread) for the task.
If the task is likely to be done often, use a thread pool instead.
Set and subscribe to timer events.
I think the call to Sleep() might be keeping you from returning from the WndProc, so your application is not processing the incomming events for 5 secs. I suggest you try to subscribe to 5 timer events in 1s, 2s,..., 5s. Like when the timer message is recieved the button text must change. I don't know a way how to do that off the top of my head.