Quoth L. D. James: > // The final step is to display this newly created widget... > m_textview.show(); > Glib::Thread::create(sigc::mem_fun(*this, &HelloWorld::cpp_app), > true); } [...] > void HelloWorld::cpp_app() > { > string texttoprint = ""; > Glib::RefPtr<Gtk::TextBuffer> m_refTextBuffer; > m_refTextBuffer = Gtk::TextBuffer::create(); > > texttoprint += > "About to run a number of c++ functions\nand display the > results\n"; > m_refTextBuffer->set_text(texttoprint); > m_textview.set_buffer(m_refTextBuffer);
This is all fine right up until that last line, which contains a subtle (but important) bug. GTK widgets (and other UI elements of most other GUI frameworks) are typically not merely thread-unsafe (as most objects are by default: can be called from any thread provided that they can be guaranteed to not be called concurrently) but actually thread-bound (can be called only from one specific thread, typically the one that created them, or a designated "main thread"). It is therefore not permitted to touch m_textview from any thread other than the main thread, which that last line is doing. (And then since this is assigning a reference to the buffer, it then becomes unsafe to further modify that buffer later in the worker thread.) In short, while this might appear to work on your machine for this contrived example, if you run it enough times in enough different environments and with different workloads (eg. more frequent text updates) it's very likely to either crash or exhibit other strange behaviour. So don't do that. Others have already pointed you at the correct solutions, and as I am not sufficiently practiced at GTK myself to give you a precise example I can only reiterate what those others have said. >From your description of what you're trying to do it seems likely that carrying out the "actual work" on a separate thread is indeed the correct thing to be doing. But you can't just play with GUI objects outside of the GUI thread. You need to use some method to convey data from one thread to another (eg. an explicitly thread-safe queue) combined with some way to get the main thread to wake up and do some processing (eg. Glib::Dispatcher or a timeout handler). In your case, I would recommend using a std::queue of text-to-be-added protected by a mutex (to make it thread-safe) combined with a Glib::Dispatcher callback that triggers the main thread to dequeue text and add it to the textview. (Though again as others have pointed out if your "actual work" is merely calling a console application or performing file/network/pipe I/O then you may want to try using the asynchronous I/O helpers instead, to avoid the extra thread.) Multithreading is hard (to get correctly, at least -- it's easy to do it wrong). Asynchronous is less hard but still confusing until you get used to the ideas. It may be worthwhile for you to read up on both of these concepts independently of GTK, then read how they apply to GTK, then finally how they apply to your applications. You're not going to find a quick and easy solution -- or at least if you do find one and try to use it without properly understanding it, you're letting yourself in for a world of hurt. _______________________________________________ gtkmm-list mailing list gtkmm-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtkmm-list