Updating widgets in a thread in a new Gtk::Window
- From: someone_else Safe-mail net
- To: gtkmm-list gnome org
- Subject: Updating widgets in a thread in a new Gtk::Window
- Date: Tue, 3 Mar 2015 01:12:32 -0500
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!
[Date Prev][
Date Next] [Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]