Hello, I was reading the gtkmm tutorial and it says "Use Glib::Dispatcher to invoke gtkmm functions from worker threads." I have two Gtk::Windows, main window and a view window.
What I would like to do is have a thread that will update some widgets (Entrys, lables, and a Glib::RefPtr<Gdk::Pixbuf>) in the second window, because after the work is done the results will be displayed in that new window. So what I did was I show the new window and then thread the worker function in the new window. The worker function updates the widgets, which I think is not thread safe because after calling the thread x amount of times, the program will crash. The following example works but sometimes my program will crash. Example: //worker.h #ifndef WORKER_H_ #define WORKER_H_ #include <gtkmm.h> class MainWindow; class TestWindow : public Gtk::Window { public: TestWindow(); virtual ~TestWindow(); bool WorkDone(); void DoWork(MainWindow* main_window); protected: Gtk::HBox m_box_main; Gtk::Entry m_entry; private: bool m_work_done; }; #endif /* WORKER_H_ */ //test.h #ifndef TEST_H_ #define TEST_H_ #include "worker.h" class MainWindow : public Gtk::Window { public: MainWindow(); virtual ~MainWindow(); void ThreadDone(); void Notify(); protected: void Button(); protected: Gtk::Button m_btn; private: Glib::Threads::Thread* m_thread; TestWindow m_test_win; Glib::Dispatcher m_dispatcher; }; #endif /* TEST_H_ */ //test.cpp #include <gtkmm.h> #include "test.h" using namespace std; MainWindow::MainWindow() { m_thread = 0; this->set_size_request(300, 300); this->add(m_btn); m_btn.set_label("Call Thread"); m_btn.signal_clicked().connect(sigc::mem_fun(*this, &MainWindow::Button)); m_dispatcher.connect(sigc::mem_fun(*this, &MainWindow::ThreadDone)); this->show_all_children(); } MainWindow::~MainWindow() { } void MainWindow::Button() { m_test_win.show(); if(!m_thread) { m_thread = Glib::Threads::Thread::create(sigc::bind(sigc::mem_fun(m_test_win, &TestWindow::DoWork), this)); m_btn.set_sensitive(false); } } void MainWindow::ThreadDone() { if(m_thread && m_test_win.WorkDone()) { m_thread->join(); m_thread = 0; m_btn.set_sensitive(true); } } void MainWindow::Notify() { m_dispatcher.emit(); } int main(int argc, char** argv) { Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "app.test"); MainWindow main_window; return app->run(main_window); } //worker.cpp #include "worker.h" #include "test.h" TestWindow::TestWindow() { m_work_done = false; this->add(m_box_main); m_box_main.pack_start(m_entry); this->show_all_children(); } TestWindow::~TestWindow() { } void TestWindow::DoWork(MainWindow* main_window) { m_work_done = false; m_entry.set_text(""); //Is this OK to do in a thread? Even for a Glib::RefPtr<Gdk::Pixbuf>? m_entry.set_text("blah"); m_work_done = true; main_window->Notify(); } bool TestWindow::WorkDone() { return m_work_done; } Thank you so much! _______________________________________________ gtkmm-list mailing list gtkmm-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtkmm-list