> When I read your post, I get the impression that you already know what's > wrong with your program. Or at least have a strong suspicion. > > You update TestWindow::m_entry in the worker thread. That's not safe. Most of > gtk+ and gtkmm are not thread-safe. You shall call widget functions only in > the main thread. > > Have you seen the example program in the gtkmm tutorial? > https://developer.gnome.org/gtkmm-tutorial/stable/sec-multithread-example.html.en > > Kjell > > Den 2015-03-03 07:12, someone_e...@safe-mail.net skrev: > > > > > 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, > > Don't do that. > > > > which I think is not thread safe > > Correct > > > > because after calling the thread x amount of times, the program will > > crash. //Is this OK to do in a thread? Even for a > > Glib::RefPtr<Gdk::Pixbuf>? m_entry.set_text("blah"); > > No, do it in the main thread (the GUI thread). >
Thank you everybody for the help. Here is how I coded it: (example) //test.h #ifndef TEST_H_ #define TEST_H_ #include "worker.h" class MainWindow : public Gtk::Window { public: MainWindow(); virtual ~MainWindow(); protected: void Button(); protected: Gtk::Button m_btn; private: TestWindow m_test_win; }; #endif /* TEST_H_ */ //worker.h #ifndef WORKER_H_ #define WORKER_H_ #include <gtkmm.h> class MainWindow; class TestWindow : public Gtk::Window { public: TestWindow(); virtual ~TestWindow(); void DoWork(); protected: Gtk::HBox m_box_main; Gtk::Entry m_entry; private: void DispatcherUpdateEntry(bool done); void ThreadUpdateEntry(); void GetDone(bool* done); private: bool m_work_done; Glib::Threads::Thread* m_thread; Glib::Dispatcher m_dispatcher; mutable Glib::Threads::Mutex m_mutex; }; #endif /* WORKER_H_ */ //test.cpp #include <gtkmm.h> #include "test.h" using namespace std; MainWindow::MainWindow() { 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)); this->show_all_children(); } MainWindow::~MainWindow() { } void MainWindow::Button() { m_test_win.show(); m_test_win.DoWork(); } 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" TestWindow::TestWindow() { m_work_done = false; this->add(m_box_main); m_box_main.pack_start(m_entry); m_dispatcher.connect(sigc::mem_fun(*this, &TestWindow::ThreadUpdateEntry)); m_thread = Glib::Threads::Thread::create(sigc::mem_fun(*this, &TestWindow::DoWork)); this->show_all_children(); } TestWindow::~TestWindow() { } void TestWindow::DoWork() { DispatcherUpdateEntry(false); //work DispatcherUpdateEntry(true); } void TestWindow::GetDone(bool* done) { Glib::Threads::Mutex::Lock lock(m_mutex); *done = m_work_done; } void TestWindow::DispatcherUpdateEntry(bool done) { { Glib::Threads::Mutex::Lock lock(m_mutex); m_work_done = done; } m_dispatcher.emit(); } void TestWindow::ThreadUpdateEntry() { m_entry.set_text("Hello"); bool done = false; GetDone(&done); if(done == true) { m_thread->join(); m_thread = 0; } } _______________________________________________ gtkmm-list mailing list gtkmm-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtkmm-list