Hello,

I'm taking a shot in the dark, but could it be because you never delete the
thread contexts and are spawning too many threads?

Further, you want all UI action to occur in the UI thread, that is the main
thread. You have your threads arranged incorrectly. Yes, updating the UI
will work from another thread *sometimes*, but there is no guarantee it
will always since Gtk is not thread-safe by default (most at least).

You want the extra thread to do work, then emit when it's done. The
Dispatcher would then call the UI updating methods. An example would be to
create a model, update the model, when you're done updating, emit to a
Dispatcher that the model is updated, have it read the model and display
it.

Some reading,
https://developer.gnome.org/gtkmm-tutorial/stable/sec-the-constraints.html.en
.

I could totally be wrong on these things, I haven't used Gtk in ~1 year.

Kevin

On Tue, Mar 3, 2015 at 12:50 AM, <[email protected]> wrote:

> 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
> [email protected]
> https://mail.gnome.org/mailman/listinfo/gtkmm-list
>



-- 
Kevin Brightwell
*BESc. and BSc. Candidate 2015*
Western University www.westernu.ca <http://www.uwo.ca>
e. [email protected] c. 647.678.4927
_______________________________________________
gtkmm-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/gtkmm-list

Reply via email to