GTKmm with Threads and Timeouts for control the refresh of a Window



GTKmm with Threads and Timeouts for control the refresh of a Window


In last days I ask for help in a problem that I had. I have resolved and I present here the solution because I consider that don't exist much information about that.


Problem:


The problem was that when I wanted to run the window with Gtk::Main::run(window) , my principal code was stopping until I was closing the window. Then the principal code was not executing and my window was not presenting any result.


When I resolved that problem I had another problem. My window refresh only when I click in it.


I solved my problems with POSIX Threads to avoid that my main code was stopped and I use signals to avoid the problem of which my window was not refresh.


Then the code is the next:


In main.cpp


#include <pthread.h>

#include <gtkmm/main.h>

.

.

.

#include "debugger.h"

.

.

.

//Next code is for Window Creation

//****************************************

Debugger *windowDebugger; //My Object Window. I utilize this variable in all my code. Without *

//the code present problems because of absence of Gtk::Main kit before


struct str_Window //I utilize this for start the pthread

{

int i;

char **c;

};


struct str_Window strW;


//*****************************************

//Window Creation from a thread

void *openWindow(void *strW)

{

struct str_Window *my_data;


my_data = (struct str_Window *) strW;

Gtk::Main kit(my_data->i, my_data->c);

Debugger window; //After Gtk::Main kit(my_data->i, my_data->c) one can star a object

//window

windowDebugger = &window; //I have to make this for can utilize the object in all my code.

Gtk::Main::run(window);

pthread_exit((void *) 0);

}

.

.

.

.

.

.

int main(int argc, char *argv[])

{

//****************WINDOW CREATION****************************************


strW.i = argc;

strW.c = argv;


pthread_setconcurrency(100);

pthread_attr_t attr;

int rc, t, status;


// Initialize and set thread detached attribute

pthread_attr_init(&attr);

pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

pthread_t threadWindow; // declare threads

pthread_create(&threadWindow,&attr,openWindow,(void *) &strW); // create threads

sleep(1); //I have to sleep my principal code only for start the window.

windowDebugger->controlUpdate(); //I utilize this for control the refresh.

.

.

.

.My code

.

.

.

.

pthread_join(threadWindow, (void **)&status);

return 0;

}


Then in all my code I utilize windowDebugger->UpdateWorldModel for change the results in the window.



I present here the code of my object. controlRefresh, refreshWindow and updateWorldModel are the important.



DEBUGGER.cpp

#include "debugger.h"

#include "worldmodel.h" //part of my code

#include <iostream>

#include <stdio.h>



extern WorldModel wm;


using namespace salt;

//using namespace Geometry;


Debugger::Debugger()

:

m_Frame_WorldModel("World Model"),

m_Frame_Command("Give me a Command"),

m_Frame_Pos("Calculated Position"),

m_Frame_MyPos("Real Position"),

m_Frame_Times("Times"),

m_HBox_Main(false, 10),

m_Label_PosX("X"), m_Label_PosY("Y"), m_Label_PosZ("Y"),

m_Label_MyPosX("X"), m_Label_MyPosY("Y"), m_Label_MyPosZ("Y"),

m_Label_Time("T"), m_Label_Cycle("C"),

m_adjustment_day(1.0, 1.0, 31.0, 1.0, 5.0, 0.0),

m_adjustment_month(1.0, 1.0, 12.0, 1.0, 5.0, 0.0),

m_adjustment_year(1998.0, 0.0, 2100.0, 1.0, 100.0, 0.0),

m_adjustment_value(0.0, -10000.0, 10000.0, 0.5, 100.0, 0.0),

m_adjustment_digits(2.0, 1.0, 5.0, 1.0, 1.0, 0.0),

m_Button_Close("Close")

{

set_title("Borregos3D Debugger Ver 0.1");


m_HBox_Main.set_border_width(10);

add(m_HBox_Main);


m_HBox_Main.pack_start(m_Frame_WorldModel);


m_VBox_WorldModel.set_border_width(5);

m_Frame_WorldModel.add(m_VBox_WorldModel);

//m_VBox.set_border_width(5);

m_VBox_WorldModel.pack_start(m_Frame_Pos);

m_HBox_Pos.set_border_width(5);

m_Frame_Pos.add(m_HBox_Pos);

m_Label_PosX.set_alignment(Gtk::ALIGN_CENTER);

m_HBox_Pos.pack_start(m_Label_PosX, Gtk::PACK_EXPAND_WIDGET, 30);

m_Label_PosY.set_alignment(Gtk::ALIGN_CENTER);

m_HBox_Pos.pack_start(m_Label_PosY, Gtk::PACK_EXPAND_WIDGET, 30);

m_Label_PosZ.set_alignment(Gtk::ALIGN_CENTER);

m_HBox_Pos.pack_start(m_Label_PosZ, Gtk::PACK_EXPAND_WIDGET, 30);


m_VBox_WorldModel.pack_start(m_Frame_MyPos);

m_HBox_MyPos.set_border_width(5);

m_Frame_MyPos.add(m_HBox_MyPos);

m_Label_MyPosX.set_alignment(Gtk::ALIGN_CENTER);

m_HBox_MyPos.pack_start(m_Label_MyPosX, Gtk::PACK_EXPAND_WIDGET, 30);

m_Label_MyPosY.set_alignment(Gtk::ALIGN_CENTER);

m_HBox_MyPos.pack_start(m_Label_MyPosY, Gtk::PACK_EXPAND_WIDGET, 30);

m_Label_MyPosZ.set_alignment(Gtk::ALIGN_CENTER);

m_HBox_MyPos.pack_start(m_Label_MyPosZ, Gtk::PACK_EXPAND_WIDGET, 30);


m_VBox_WorldModel.pack_start(m_Frame_Times);

m_HBox_Times.set_border_width(5);

m_Frame_Times.add(m_HBox_Times);

m_Label_Time.set_alignment(Gtk::ALIGN_CENTER);

m_HBox_Times.pack_start(m_Label_Time, Gtk::PACK_EXPAND_WIDGET, 30);

m_Label_Cycle.set_alignment(Gtk::ALIGN_CENTER);

m_HBox_Times.pack_start(m_Label_Cycle, Gtk::PACK_EXPAND_WIDGET, 30);



//Close button:

m_HBox_Main.pack_start(m_Frame_Command);


m_VBox_Command.set_border_width(1);

m_Frame_Command.add(m_VBox_Command);


m_Button_Close.signal_clicked().connect( sigc::mem_fun(*this, &Debugger::on_button_close) );

m_VBox_Command.pack_start(m_Button_Close, Gtk::PACK_SHRINK);


show_all_children();

}

Debugger::~Debugger()

{

}


//This function control the refresh, it refresh every 250 milliseconds.

void Debugger::controlUpdate()

{

sigc::slot<bool> my_slot = sigc::bind(sigc::mem_fun(*this, &Debugger::refreshWindow),4);

// I don't know but I have to give some variable, in this ocassion 4 to the function that will execute

//repeatably

sigc::connection conn = Glib::signal_timeout().connect(my_slot, 250);

}



void Debugger::on_button_close()

{

hide();

}

//update

void Debugger::Update_WorldModel()

{ Vector3f RealPos = wm.GetMyPosition();

Vector3f DebugPosition = wm.GetMyDebugPosition();

char PosX[10];

char PosY[10];

char PosZ[10];

char MyPosX[10];

char MyPosY[10];

char MyPosZ[10];

char time[10];

char cycleTime[10];

sprintf(PosX, "%.3f", RealPos[0]);

sprintf(PosY, "%.3f", RealPos[1]);

sprintf(PosZ, "%.3f", RealPos[2]);

sprintf(MyPosX, "%.3f", DebugPosition[0]);

sprintf(MyPosY, "%.3f", DebugPosition[1]);

sprintf(MyPosZ, "%.3f", DebugPosition[2]);

sprintf(time, "%.3f", wm.GetTime());

sprintf(cycleTime, "%d", wm.GetSimTime());

m_Label_PosX.set_text(PosX);

m_Label_PosY.set_text(PosY);

m_Label_PosZ.set_text(PosZ);

m_Label_MyPosX.set_text(MyPosX);

m_Label_MyPosY.set_text(MyPosY);

m_Label_MyPosZ.set_text(MyPosZ);

m_Label_Time.set_text(time);

m_Label_Cycle.set_text(cycleTime);

// show_all_children();

// draw(0);

// if(Gtk::Main::instance()->events_pending()){

// Gtk::Main::instance()->iteration();

// }

// return true;

}


bool Debugger::refreshWindow(int n){

queue_draw(); //refresh the window

return true; //without this the signal will died

}



Finally I have to say that I utilized gtkmm2.4, if one want utilize gtkmm2.0 one must redefine the function Debugger::controlUpdate() because the the sigc is different.


I think that is all, I hope that this can help somebody. I consider that If were exist more documentation this will more simple. I last 3 weeks because of that......



César Omar Flores García

cesar7 gmail com



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