Re: Window will not expose



On 01/25/2009 05:01 PM, Evan White wrote:
Some of you may have helped me out in the Gtk forums or have at least
read some of my stupid post. I have found that using mailing lists are
much more helpful than forums are. I am not a heavy programmer I have
only had two C++ courses in college. I am in my senior year working on
my engineering design project where my group is
building a replacement for your vehicle's instrument cluster.
I have been able to get the window to expose when I first run my program
but now I am trying to animate my cairo drawing using values being read
in from a text file line by line (This is for test purposes our intent
is for the software to receive values from the vehicle itself). I am
able to get the window to expose and draw the intial screen but when it
starts to read the text file my callback that I use to invalidate the
drawing surface and force the window to re-expose and draw to the screen
based on the text file data I end up in and infinite loop where my
signal keeps calling my callback but the window is never exposed again.
Does anyone know why this is happening

Here is my code below:

Default::Default(void) {
currentSpeedValue = 0;
currentRpmValue = 0;
currentFuelValue = 0;
initialize = true;

file_read = Glib::IOChannel::create_from_file("test.txt", "r");
Glib::signal_io().connect(sigc::mem_fun(*this, &Default::Update),
file_read, Glib::IO_IN | Glib::IO_HUP);
#ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
//Connect the signal handler if it isn't already a virtual method override:
signal_expose_event().connect(sigc::mem_fun(*this,
&Clock::on_expose_event), false);
#endif //GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
}

bool Default::Update(Glib::IOCondition io_condition) { // force the
program to redraw the screen
Glib::RefPtr<Gdk::Window> win = get_window();
if (win) {
cout << "forcing\n";
Gdk::Rectangle r(0, 0, get_allocation().get_width(),
get_allocation().get_height());
win->invalidate_rect(r, false);
cout << "invalidated\n";
}
cout << "bye\n\n";
return true;
}

// use this to draw the intial screen
bool Default::on_expose_event(GdkEventExpose* event) {
cout << "exposing\n";
Glib::RefPtr<Gdk::Window> window = get_window();
if(window) {
Gtk::Allocation allocation = get_allocation();
totalDrawableWidth = allocation.get_width();
totalDrawableHeight = allocation.get_height();
cr = window->create_cairo_context(); cr->rectangle(event->area.x,
event->area.y, event->area.width, event->area.height);
cr->clip();
if(!initialize) {
cout << "Updating....\n";

Glib::ustring buf;
cout << "created the buffer\n";
#ifdef GLIBMM_EXCEPTIONS_ENABLED
file_read->read_line(buf);
cout << "read in a line\n";
#else
auto_ptr<Glib::Error> ex;
file_read->read_line(buf, ex);
if(ex.get()) {
cout << "ouch\n";
cerr << "Error: " << ex->what() << endl;
}
#endif //GLIBMM_EXCEPTIONS_ENABLED
string temp = buf.raw();
string tempVal = temp.substr(2, temp.length()-1);
temp.erase(1, temp.length()-1);
int SensID = atoi(temp.c_str());
double value = atof(tempVal.c_str());
cout << "data received\n";
switch(SensID) {
case 0:
cout << "speed baby\n";
processSpeed(value);
break;
case 1:
processRPM(value);
break;
case 2:
processFuel(value);
break;
default:
cerr << "no luck bud\n";
break;
} }
else {
// Draw initial gauges
drawGauge(gaugePadding*totalDrawableWidth); // Speed Gauge
drawGauge((gaugeWidth + gaugePadding)*totalDrawableWidth); // RPM Gauge
drawNeedle(180, gaugePadding*totalDrawableWidth); // Speed Needle
drawNeedle(180, (gaugeWidth + gaugePadding)*totalDrawableWidth); // RPM
Needle
drawFuelGauge(0);
initialize = false;
cout << "DONE INTIALIZATION\n";
}
}
return true;
}



What exactly do you mean by 'the window is never exposed again'? Do you mean that the expose handler is never called again or that the widget is never re-drawn?

It's hard to know exactly what the problem is, since we dont' have the full code. for example, I don't know what e.g. processSpeed() does. Is it supposed to draw anything? Because from what I can tell, you only draw your guages the first time through (e.g. 'if (!initialize)...'). My guess is that you should probably do everything in the else branch every time, not just the first time, but it's hard to know without seeing any more of the code.

A suggestion: don't worry about the GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED and GLIBMM_EXCEPTIONS_ENABLED macros. Just figure out if the target environment you're going to be using is built with or without those features and then use one or the other. It just makes the code hard to read and it's too difficult to get right unless you're actively testing both configurations. (I still sort of wish the option to disable those didn't exist, but that's a separate issue).

Also, I would do the IO reading / processing in the signal_io() handler rather than in the expose event handler, since I believe several expose events can be combined together so the behavior might be more predictable if you do it in the io handler.

hope that helps
jonner


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