Re: Updating widgets in a thread in a new Gtk::Window



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.

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, <someone_else safe-mail net> 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
gtkmm-list gnome org
https://mail.gnome.org/mailman/listinfo/gtkmm-list



--
Kevin Brightwell
BESc. and BSc. Candidate 2015
Western University www.westernu.ca
e. kevin brightwell2 gmail com c. 647.678.4927



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]