2011/2/14 BALLABIO GERARDO <gerardo.balla...@esterni.gruppo.mps.it>:
> Hi all,
> in the last weekend I upgraded my computer to the new stable version of 
> Debian (version 6.0.0, released a few days ago). After the upgrade, a gtkmm 
> program of mine has become less responsive to the point of being barely 
> usable. Apparently the dispatching of signals is now much slower than it used 
> to be, and when a lot of them are connected (in my program there are more 
> than 100), it becomes very noticeable.

The slowdown is not caused by signal emission, but by modify_bg. If
you write a custom expose handler that draws the cells, the updates
are instantaneous. See the attached file.

Regards, Krzysztof
#include <gtkmm.h>

class Cell : public Gtk::EventBox
{
private:
  int number;
protected:
  sigc::signal<void, int> activate;
  virtual bool on_enter_notify_event(GdkEventCrossing *event)
  { activate.emit(number); return true; }
  virtual bool on_expose_event(GdkEventExpose *event)
  {
    Glib::RefPtr<Gdk::Window> window = get_window();
    if (!window) return true;

    Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
    if(event) {
        cr->rectangle(event->area.x,     event->area.y,
                      event->area.width, event->area.height);
        cr->clip();
    }

    switch(state) {
      case 0:
        cr->set_source_rgb(1, 0, 0);
        break;
      case 1:
        cr->set_source_rgb(0, 1, 0);
        break;
      default:
        cr->set_source_rgb(0, 0, 1);
        break;
    }
    cr->paint();

    return true;
  }
public:
  Cell() {
    add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::EXPOSURE_MASK);
    set_app_paintable(true);
  }
  void set_number(int n) { number = n; }
  sigc::signal<void, int> &signal_activate() { return activate; }
  int state;
};

class MainWindow : public Gtk::Window
{
private:
  static const int rows = 20, cols = 20, cellsize = 20;

  Gtk::Table table;
  Cell cell[rows*cols];
  int active;

  void set_active(int n);
public:
  MainWindow();
};

MainWindow::MainWindow()
{
  set_default_size(cols * cellsize, rows * cellsize);
  add(table);
  table.set_homogeneous(true);
  table.set_row_spacings(2);
  table.set_col_spacings(2);

  // set up cells
  for (int i=0; i<rows*cols; ++i)
    {
      cell[i].set_number(i);
      int irow = i / rows, icol = i % rows;
      table.attach(cell[i], irow, irow + 1, icol, icol + 1);

      // connect signal
      cell[i].signal_activate().connect
	(sigc::mem_fun(*this, &MainWindow::set_active));
    }
  set_active(-rows - 1); // start with no active row nor column

  show_all_children();
}

void MainWindow::set_active(int n)
{
  active = n;

  // update cell colors
  const Gdk::Color colors[] = {
    Gdk::Color("red"), Gdk::Color("green"), Gdk::Color("blue"),
  };
  int arow = active / rows, acol = active % rows;
  for (int i=0; i<rows*cols; ++i)
    {
      int irow = i / rows, icol = i % rows,
	col = (irow == arow ? 1 : 0) + (icol == acol ? 1 : 0);
      
      cell[i].state = col;
      //cell[i].queue_draw();
    }

  // redraw
  queue_draw();
}

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);
  MainWindow window;
  Gtk::Main::run(window);

  return 0;
}
_______________________________________________
gtkmm-list mailing list
gtkmm-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Reply via email to