Gtkmm: Adding Window at later time - c++

Because I´m writting a "generic" application behaving completely different when facing other configurations, I´m forced to show gtk windows even if I dont yet know them at startup. There might also be the requirement that multiple windows need to be visisble (not modal dialogs but standalone windows) at the same time. But, it would be great if one can simply start one gtk event loop at startup.
Is is somehow possible to add windows to that loop after it has been started?
While I found the Gtk::Application class which seems to support exactly the indented behaviour I´m restricted to use the Gtk::Main class.

There's only a single Gtk::Main object allowed. Widgets should be created in the same thread the main event loop is being run in. To work around this limitation you need to develop a way to pass your window creation commands to the gtk thread.
The simplest way is to use Glib::Dispatcher
struct WindowBuilder {
/**/
Glib::Dispatcher* signal_create;
void create_window() {
//From main thread...
signal_create->emit();
}
}
void create_mainWnd() {
new Ui::MainWnd();
}
//From Gtk thread...
builder->signal_create->connect(sigc::ptr_fun(create_mainWnd));
Gtk::Main::run();
Glib::Dispatcher doesn't take any arguments with it, so next step is to figure out how to pass arguments around between threads.
For different types of windows you can just use different disptachers.
boost::asio::io_service can help you pass messages around.
while(!exit) {
io_service.reset();
io_service.poll();
while(Gtk::Main::events_pending())
Gtk::Main::iteration();
Sleep(0);
}

Related

How to use threads with multiple windows in C++?

I'm trying to build an application that can spawn a window on a separate thread. Let me explain a simple version. My main creates an object that has a window, let's call this object a menu. From the menu you can select what to do, for example open up an image to a new window. This whole object, or the object's "game loop" needs to be on a separate thread so that I can still keep interacting with the menu. I also need to interact with the image viewer.
My question is, what is the proper way of doing this?
I haven't really used threads a lot before. But from what I understand I need to detach the thread to create a daemon thread.
I tried to play around with the thread to create this but I kept getting these errors:
Failed to activate the window's context
Failed to activate OpenGL context: The requested resource is in use.
I'm not certain what causes this, all objects, like my windows are different instances. The application will still run fine even with these errors.
My application is quite big so here's an extremely simplified version of the code I've tried.
int main()
{
Menu menu; // this spawns a window
menu.run(); // let's say for simplicity this doesn't do anything else other than
// create a new window (the image viewer)
}
...
void caller(Image_view *img_view)
{
img_view->run();
}
void Menu::run()
{
Image_view *img_view = new Image_view(); // This creates the window
this->thread = new std::thread(caller, img_view);
this->thread->detach();
while (1); // This is here to keep the application running,
// in a real application this method would look different.
// This whole thread call would be in an event handler instead,
// but for this example I tried to make it as simple as possible
}
...
void Image_view::run()
{
while (running)
{
update(); // Event handler and whatever
render(); // Renders the image and whatever
}
this->window->close();
}
I mostly want to know if I'm using the thread correctly or not in an application like this. Also if you have any insight as to what the error message means, explaining it would be greatly appreciated. I should also mention that I'm using SFML for rendering and creating the window instance.
The tutorials I found about the threads are always something extremely simple which doesn't involve any window or anything that could for example cause that error message. So I figured someone smarter here might know the proper use of the thread in my case.
Thanks in advance!

How to have Qt embedded into another app (non-blocking way)

I am using a 3D rendering C++ API and want to use Qt to display GUIs on top of it.
My rendering API runs in the main() application thread, just like Qt wants.
At first I tried to run Qt in it's own std::thread and it worked perfectly fine - and I have no idea what Qt's doc means with
As mentioned, each program has one thread when it is started. This
thread is called the "main thread" (also known as the "GUI thread" in
Qt applications). The Qt GUI must run in this thread
https://doc.qt.io/qt-5/thread-basics.html
This is either plain wrong or poorly written...
My std::thread worker looks something like this:
int SomeClass::qt_app_worker(size_t width, size_t height, const std::string& title, const std::string& contents) {
int argc = 0;
QApplication app(argc, NULL);
// QDialog here
return app.exec();
}
The problem is then I can't do anything with this Qt app because if I try to create say another QDialog from the main() thread, Qt will complain I can only do this from the thread owning my QApplication (qt_app_worker).
So I'm either permanently locked out of the qt_app_worker thread, or I have to implement my own message queue for EVERYTHING Qt-related.
I sketched it with a derived QApplication class using startTimer() and then handling custom messages in timerEvent(...) but this is just too much hassle.
I just don't understand why Qt won't let a user run it in a separate thread, hopefully I'm just missing something.
There are (at least) two built-in thread-safe ways to communicate with the GUI thread (which is usually the "main thread" of Qt application, which is why it is often called main thread, and for Qt point of view it is).
You can post events (including your own custom event subclasses) to the thread using QCoreApplication::postEvent.
You can invoke methods of objects in another thread, provided you do so with Qt::QueuedConnection or Qt::BlockingQueuedConnection connection type using QMetaObject::invokeMethod (and its different overloads).
Communication the other way, from Qt to you own main thread, can happen in a few ways. I believe using Qt::BlockingQueuedConnection also allow getting a return value, but you probably don't want that blocking.... So you can just use any of the usual methods of communicating between threads, not limited by Qt, such as simply atomic or mutex-protected variables which are set from Qt, and your threads polls or otherwise reads when relevant (such as at start of every frame). Or make a simple message queue, if you want to be able to track every change and not just the state at the start of a frame or whatever.

Issue with Freeze() , Thaw() function in wxwidgets in linux

I did project in window using wxwidgets then i am trying to run it linux but i am getting some problem with freeze&thaw function.
Will it work with linux? Is there any other option to freeze the window?
Here is mycode:
void *UpdateModeltreeThread::Entry()
{
m_PtrTree->Freeze();
m_PtrTree->ProcessUpdateModelTree();
m_PtrTree->Thaw();
return NULL;
}
Note: i am running above thing using wxThread
ProcessUpdateModelTree() in this function i am adding treeitems to wxtreelistctrl there are number of treeitems are there so i am using freeze&thaw,running at back end using thread function its working in windows but not in linux
Issue:In middle of Freeze() & Thaw() its calling paint event , because ot that its crashing in treelistctrl paint event,but this thing is not happing in window
You absolutely cannot call GUI methods such as Freeze() and Thaw() from worker threads, as you seem to be doing here. You must call them or, better, use safer wxWindowUpdateLocker from the main thread.

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();

wxWidgets (or even OOP GUI) Multiple Windows

I'm kind of stuck on something; regarding spawning multiple forms in OOP.
The message loop most of the time is (wxWidget's case) window->show();
bool MyApp::OnInit()
{
MainWindow *oWindow = new MainWindow(wxT("My Window"));
oWindow->Show(true);
return true;
}
Others have oWindow->run(), but anyway my question is:
I've created a second thread with the exact same structure of the function above and called the message loop method. The problem is that the window appears and dissapears suddenly which doesn't make sense to me. If however I call:
MainWindow *oWindow = new MainWindow(wxT("My Window"));
oWindow->Show(true);
MainWindow *oWindow2 = new MainWindow(wxT("My Window"));
oWindow2->Show(true);
It will work, but I don't want that as I will need to keep track of the windows I create and have them on separate threads. What can I do?
You cannot run wxWidgets windows in anything other than the main thread.
"GUI calls, such as those to a wxWindow or wxBitmap are explicitly not safe at all in secondary threads and could end your application prematurely. This is due to several reasons, including the underlying native API and the fact that wxThread does not run a GUI event loop similar to other APIs as MFC."
http://docs.wxwidgets.org/2.8/wx_wxthread.html
BTW, I cannot imagine any situation where what you want to do is a good idea. There is never any need to tun windows in more than one thread.
A windows program is event-driven. You can as have as many top level windows as you want, but there should be just one event queue so that the events on two windows do not end up in contention for the same resource. This is why wxWidgets prevents you trying to create two threads both handling windows events.