0

Want to programatically activate a gtkmm columnview but when I set up the handler and then call the activate() member it does not invoke the handler. I have modified a simple example of the columnview class as per the gtkmm examples. The header file is below:


#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  ~ExampleWindow() override;

protected:
  // Signal handlers:
  void on_button_quit();
  void on_setup_label(const Glib::RefPtr<Gtk::ListItem>& list_item, Gtk::Align halign);
  void on_setup_progressbar(const Glib::RefPtr<Gtk::ListItem>& list_item);
  void on_bind_id(const Glib::RefPtr<Gtk::ListItem>& list_item);
  void on_bind_name(const Glib::RefPtr<Gtk::ListItem>& list_item);
  void on_bind_number(const Glib::RefPtr<Gtk::ListItem>& list_item);
  void on_bind_percentage(const Glib::RefPtr<Gtk::ListItem>& list_item);
  void on_columnview_activate(guint position);

  // A Gio::ListStore item.
  class ModelColumns : public Glib::Object
  {
  public:
    unsigned int m_col_id;
    Glib::ustring m_col_name;
    short m_col_number;
    int m_col_percentage;

    static Glib::RefPtr<ModelColumns> create(unsigned int col_id,
      const Glib::ustring& col_name, short col_number, int col_percentage)
    {
      return Glib::make_refptr_for_instance<ModelColumns>(
        new ModelColumns(col_id, col_name, col_number, col_percentage));
    }

  protected:
    ModelColumns(unsigned int col_id, const Glib::ustring& col_name,
      short col_number, int col_percentage)
    : m_col_id(col_id), m_col_name(col_name), m_col_number(col_number),
      m_col_percentage(col_percentage)
    {}
  }; // ModelColumns

  // Child widgets:
  Gtk::Box m_VBox;
  Gtk::ScrolledWindow m_ScrolledWindow;
  Gtk::ColumnView m_ColumnView;
  Gtk::Box m_ButtonBox;
  Gtk::Button m_Button_Quit;

  Glib::RefPtr<Gio::ListStore<ModelColumns>> m_ListStore;
};

#endif //GTKMM_EXAMPLEWINDOW_H

The cpp file is below:


#include "examplewindow.h"

ExampleWindow::ExampleWindow()
: m_VBox(Gtk::Orientation::VERTICAL),
  m_Button_Quit("Quit")
{
  set_title("Gtk::ColumnView (Gio::ListStore) example");
  set_default_size(500, 250);

  m_VBox.set_margin(5);
  set_child(m_VBox);

  // Add the ColumnView, inside a ScrolledWindow, with the button underneath:
  m_ScrolledWindow.set_child(m_ColumnView);

  // Only show the scrollbars when they are necessary:
  m_ScrolledWindow.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
  m_ScrolledWindow.set_expand();

  m_VBox.append(m_ScrolledWindow);
  m_VBox.append(m_ButtonBox);

  m_ButtonBox.append(m_Button_Quit);
  m_ButtonBox.set_margin(5);
  m_Button_Quit.set_hexpand(true);
  m_Button_Quit.set_halign(Gtk::Align::END);
  m_Button_Quit.signal_clicked().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_button_quit));

  // Create the List model:
  m_ListStore = Gio::ListStore<ModelColumns>::create();
  m_ListStore->append(ModelColumns::create(1, "Billy Bob", 10, 15));
  m_ListStore->append(ModelColumns::create(2, "Joey Jojo", 20, 40));
  m_ListStore->append(ModelColumns::create(3, "Rob McRoberts", 30, 70));

  // Set list model and selection model.
  auto selection_model = Gtk::SingleSelection::create(m_ListStore);
  selection_model->set_autoselect(false);
  selection_model->set_can_unselect(true);
  m_ColumnView.set_model(selection_model);
  m_ColumnView.add_css_class("data-table"); // high density table

  // Make the columns reorderable.
  // This is not necessary, but it's nice to show the feature.
  m_ColumnView.set_reorderable(true);

  // Add the ColumnView's columns:

  // Id column
  auto factory = Gtk::SignalListItemFactory::create();
  factory->signal_setup().connect(sigc::bind(sigc::mem_fun(*this,
    &ExampleWindow::on_setup_label), Gtk::Align::END));
  factory->signal_bind().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_bind_id));
  auto column = Gtk::ColumnViewColumn::create("ID", factory);
  m_ColumnView.append_column(column);

  // Name column
  factory = Gtk::SignalListItemFactory::create();
  factory->signal_setup().connect(sigc::bind(sigc::mem_fun(*this,
    &ExampleWindow::on_setup_label), Gtk::Align::START));
  factory->signal_bind().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_bind_name));
  column = Gtk::ColumnViewColumn::create("Name", factory);
  m_ColumnView.append_column(column);

  // Number column
  factory = Gtk::SignalListItemFactory::create();
  factory->signal_setup().connect(sigc::bind(sigc::mem_fun(*this,
    &ExampleWindow::on_setup_label), Gtk::Align::END));
  factory->signal_bind().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_bind_number));
  column = Gtk::ColumnViewColumn::create("Formatted number", factory);
  m_ColumnView.append_column(column);

  // Percentage column
  factory = Gtk::SignalListItemFactory::create();
  factory->signal_setup().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_setup_progressbar));
  factory->signal_bind().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_bind_percentage));
  column = Gtk::ColumnViewColumn::create("Some percentage", factory);
  m_ColumnView.append_column(column);

   m_ColumnView.signal_activate().connect(
     sigc::mem_fun(
        *this,
        &ExampleWindow::on_columnview_activate
     )
      );

   m_ColumnView.activate();
   printf("After columnview activate called.\n");
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::on_button_quit()
{
  set_visible(false);
}

void ExampleWindow::on_columnview_activate(guint position)
{
   printf("Columnview activate routine called for row %d.\n", position);
}

void ExampleWindow::on_setup_label(
  const Glib::RefPtr<Gtk::ListItem>& list_item, Gtk::Align halign)
{
  list_item->set_child(*Gtk::make_managed<Gtk::Label>("", halign));
}

void ExampleWindow::on_setup_progressbar(
  const Glib::RefPtr<Gtk::ListItem>& list_item)
{
  auto progressbar = Gtk::make_managed<Gtk::ProgressBar>();
  progressbar->set_show_text(true);
  list_item->set_child(*progressbar);
}

void ExampleWindow::on_bind_id(const Glib::RefPtr<Gtk::ListItem>& list_item)
{
  auto col = std::dynamic_pointer_cast<ModelColumns>(list_item->get_item());
  if (!col)
    return;
  auto label = dynamic_cast<Gtk::Label*>(list_item->get_child());
  if (!label)
    return;
  label->set_text(Glib::ustring::format(col->m_col_id));
}

void ExampleWindow::on_bind_name(const Glib::RefPtr<Gtk::ListItem>& list_item)
{
  auto col = std::dynamic_pointer_cast<ModelColumns>(list_item->get_item());
  if (!col)
    return;
  auto label = dynamic_cast<Gtk::Label*>(list_item->get_child());
  if (!label)
    return;
  label->set_text(col->m_col_name);
}

void ExampleWindow::on_bind_number(const Glib::RefPtr<Gtk::ListItem>& list_item)
{
  auto col = std::dynamic_pointer_cast<ModelColumns>(list_item->get_item());
  if (!col)
    return;
  auto label = dynamic_cast<Gtk::Label*>(list_item->get_child());
  if (!label)
    return;
  // 10 digits, using leading zeroes.
  label->set_text(Glib::ustring::sprintf("%010d", col->m_col_number));
}

void ExampleWindow::on_bind_percentage(const Glib::RefPtr<Gtk::ListItem>& list_item)
{
  auto col = std::dynamic_pointer_cast<ModelColumns>(list_item->get_item());
  if (!col)
    return;
  auto progressbar = dynamic_cast<Gtk::ProgressBar*>(list_item->get_child());
  if (!progressbar)
    return;
  progressbar->set_fraction(col->m_col_percentage * 0.01);
}

If I double click on a row then the activate handler will be called, but not when I call activate() manually. I have been converting from gtkmm 4.8 to 4.10 and in the past could use a treeview but is now deprecated. Activating a treeview via code worked in the past.

  1. Created simple example as per forum request.
  2. Compiled and ran code and only works as discussed above.
SRB
  • 1
  • 2

0 Answers0