我在 Gtk::TreeView 中的自定义列不起作用
my custom column in a Gtk::TreeView doesn't work
我有一个 Gtk::TreeView
,我在其中添加了一个模型和一个自定义列:
examplewindow.hh :
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H
#include <gtkmm.h>
class ExampleWindow
: public Gtk::Window
{
public:
ExampleWindow(void);
virtual ~ExampleWindow(void);
//My column
class foocol
: public Gtk::TreeView::Column
{
public:
Gtk::CellRendererToggle fooRenderer;
bool test;
foocol(void);
~foocol(void);
foocol(const foocol&);
foocol &operator=(const foocol&);
private:
//signal
void foocolData(Gtk::CellRenderer*,const Gtk::TreeModel::iterator&);
void foocolToggled(const Glib::ustring&);
};
//Tree model columns:
class ModelColumns : public Gtk::TreeModel::ColumnRecord
{
public:
ModelColumns(void){ add(m_col_id); add(m_col_name); }
Gtk::TreeModelColumn<unsigned int> m_col_id;
Gtk::TreeModelColumn<Glib::ustring> m_col_name;
Gtk::TreeModelColumn<ExampleWindow::foocol> m_col_foocol;
};
foocol m_foocol; // XXX
ModelColumns m_Columns;
//Child widgets:
Gtk::TreeView m_TreeView;
Glib::RefPtr<Gtk::ListStore> m_refTreeModel;
};
#endif //GTKMM_EXAMPLEWINDOW_H
examplewindow.cc :
#include <iostream>
#include "examplewindow.hh"
#define CB_FUNCTION(X) sigc::mem_fun( this, &ExampleWindow::foocol::X )
#define CONNECT(X) connect( sigc::mem_fun( this,\
&ExampleWindow::foocol::X ) );
ExampleWindow::ExampleWindow()
{
set_title("List of singers");
set_border_width(5);
set_default_size(400, 200);
//Add the TreeView, inside the window
add(m_TreeView);
//Create the Tree model:
m_refTreeModel = Gtk::ListStore::create(m_Columns);
m_TreeView.set_model(m_refTreeModel);
//Fill the TreeView's model
Gtk::TreeModel::Row row = *(m_refTreeModel->append());
row[m_Columns.m_col_id] = 1;
row[m_Columns.m_col_name] = "Marilyn Manson";
row = *(m_refTreeModel->append());
row[m_Columns.m_col_id] = 2;
row[m_Columns.m_col_name] = "David Vincent";
row = *(m_refTreeModel->append());
row[m_Columns.m_col_id] = 3;
row[m_Columns.m_col_name] = "Yolandi Visser";
//Add the TreeView's view columns:
//This number will be shown with the default numeric formatting.
m_TreeView.append_column( "ID", m_Columns.m_col_id );
m_TreeView.append_column( "Name", m_Columns.m_col_name );
m_TreeView.append_column( "model.m_col_foocol", m_Columns.m_col_foocol );
m_TreeView.append_column( m_foocol ); // XXX
show_all_children();
}
ExampleWindow::~ExampleWindow()
{
}
ExampleWindow::foocol::foocol( )
{
std::cout << "foocol constructor " << this << "\n";
this->set_title( "foocol" );
this->pack_start( fooRenderer );
//Tell the view column how to render the model values
this->set_cell_data_func( fooRenderer, CB_FUNCTION( foocolData ) );
fooRenderer.property_sensitive() = true; // done by default
fooRenderer.signal_toggled().CONNECT( foocolToggled );
}
ExampleWindow::foocol::~foocol( )
{
std::cout << "foocol destructor " << this << "\n";
}
ExampleWindow::foocol::foocol( const ExampleWindow::foocol& copyMe )
: test(copyMe.test)
{
std::cout << "foocol copy constructor " << this << "\n";
}
ExampleWindow::foocol&
ExampleWindow::foocol::operator=( const ExampleWindow::foocol& copyMe )
{
std::cout << "assignement " << this << " = " << ©Me << "\n";
return *this;
}
/********* SIGNALS ******/
void
ExampleWindow::foocol::foocolData( Gtk::CellRenderer* renderer
, const Gtk::TreeModel::iterator&
iter )
{
std::cout << "foocolData " << this << "\n";
}
void
ExampleWindow::foocol::foocolToggled( const Glib::ustring& path )
{
std::cout << "foocolToggled " << this << "\n";
}
main.cc :
#include <iostream>
#include "examplewindow.hh"
#include <gtkmm/application.h>
int main( int argc
, char *argv[] )
{
Glib::RefPtr<Gtk::Application> app
= Gtk::Application::create( argc, argv
, "org.gtkmm.example" );
ExampleWindow window;
//Shows the window and returns when it is closed.
return app->run( window );
}
在 linux 上编译:
g++ examplewindow.cc main.cc `pkg-config gtkmm-3.0 --cflags --libs` -std=c++11
在 windows 上编译:
我不是种族主义者,我只是不知道如何在 windows 上编译。
截图:
问题:
好的,正如您所看到的,我花了一些时间来为我的问题举一个很好的例子。在屏幕截图上,您可以看到一个名为 foocol
的列,您可以在其中看到一个切换按钮,在左侧,您可以看到一个名为 model.mcolfoocol
.
的列
第二列是我的问题所在,我根本看不到切换。我不知道为什么,我花了好几个小时都没能解决这个问题...
两列相同,不同的结果来自作为列添加的一列,而第二列(不起作用的列)是通过 Gtk::TreeModel::ColumnRecord
添加的。当然要用第二种方法了...
最好在我添加 // XXX
的行添加注释,这样控制台中的所有消息都会与问题相关。
可能的输出:
foocol constructor 0xbfda6e70
(a.out:12545): Gtk-CRITICAL **: gtk_cell_layout_add_attribute: assertion 'column >= 0' failed
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocol destructor 0xbfda6e70
不幸的是,我不知道如何调试使用多个库的程序。我什至不确定我的计算机是否有足够的内存来执行此操作...
真心觉得gtkmm这部分不直观...
您可能不想使用 ExampleWindow::foocal 作为模型支持类型(在 Gtk::TreeModelColumn m_col_foocol; 中);您正在混合使用 TreeModel 和 TreeView 类型。
我不确定您的意图(您为什么不只使用 TreeModelColumn,它会自动呈现一个复选框)。
下面我强制您的专栏注册 Model 的 ColumnRecord,并注册 View,并显示(并生成切换事件,但未正确切换);注意我需要改变它的类型;希望这会帮助您朝着理想的方向前进。
我已经注释掉标有 // XXX 的行,并且还修改了:
examplewindow.h 变化
//My column
class foocol
- : public Gtk::TreeView::Column
+ : public Gtk::TreeView::Column, public Gtk::TreeModelColumn<bool>
{
...
- ModelColumns(void){ add(m_col_id); add(m_col_name); }
+ ModelColumns(void){ add(m_col_id); add(m_col_name); add (m_col_foocol); }
...
- Gtk::TreeModelColumn<ExampleWindow::foocol> m_col_foocol;
+ foocol m_col_foocol;
examplewindow.cc
- m_TreeView.append_column( "model.m_col_foocol", m_Columns.m_col_foocol );
+ m_TreeView.append_column( m_Columns.m_col_foocol );
我有一个 Gtk::TreeView
,我在其中添加了一个模型和一个自定义列:
examplewindow.hh :
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H
#include <gtkmm.h>
class ExampleWindow
: public Gtk::Window
{
public:
ExampleWindow(void);
virtual ~ExampleWindow(void);
//My column
class foocol
: public Gtk::TreeView::Column
{
public:
Gtk::CellRendererToggle fooRenderer;
bool test;
foocol(void);
~foocol(void);
foocol(const foocol&);
foocol &operator=(const foocol&);
private:
//signal
void foocolData(Gtk::CellRenderer*,const Gtk::TreeModel::iterator&);
void foocolToggled(const Glib::ustring&);
};
//Tree model columns:
class ModelColumns : public Gtk::TreeModel::ColumnRecord
{
public:
ModelColumns(void){ add(m_col_id); add(m_col_name); }
Gtk::TreeModelColumn<unsigned int> m_col_id;
Gtk::TreeModelColumn<Glib::ustring> m_col_name;
Gtk::TreeModelColumn<ExampleWindow::foocol> m_col_foocol;
};
foocol m_foocol; // XXX
ModelColumns m_Columns;
//Child widgets:
Gtk::TreeView m_TreeView;
Glib::RefPtr<Gtk::ListStore> m_refTreeModel;
};
#endif //GTKMM_EXAMPLEWINDOW_H
examplewindow.cc :
#include <iostream>
#include "examplewindow.hh"
#define CB_FUNCTION(X) sigc::mem_fun( this, &ExampleWindow::foocol::X )
#define CONNECT(X) connect( sigc::mem_fun( this,\
&ExampleWindow::foocol::X ) );
ExampleWindow::ExampleWindow()
{
set_title("List of singers");
set_border_width(5);
set_default_size(400, 200);
//Add the TreeView, inside the window
add(m_TreeView);
//Create the Tree model:
m_refTreeModel = Gtk::ListStore::create(m_Columns);
m_TreeView.set_model(m_refTreeModel);
//Fill the TreeView's model
Gtk::TreeModel::Row row = *(m_refTreeModel->append());
row[m_Columns.m_col_id] = 1;
row[m_Columns.m_col_name] = "Marilyn Manson";
row = *(m_refTreeModel->append());
row[m_Columns.m_col_id] = 2;
row[m_Columns.m_col_name] = "David Vincent";
row = *(m_refTreeModel->append());
row[m_Columns.m_col_id] = 3;
row[m_Columns.m_col_name] = "Yolandi Visser";
//Add the TreeView's view columns:
//This number will be shown with the default numeric formatting.
m_TreeView.append_column( "ID", m_Columns.m_col_id );
m_TreeView.append_column( "Name", m_Columns.m_col_name );
m_TreeView.append_column( "model.m_col_foocol", m_Columns.m_col_foocol );
m_TreeView.append_column( m_foocol ); // XXX
show_all_children();
}
ExampleWindow::~ExampleWindow()
{
}
ExampleWindow::foocol::foocol( )
{
std::cout << "foocol constructor " << this << "\n";
this->set_title( "foocol" );
this->pack_start( fooRenderer );
//Tell the view column how to render the model values
this->set_cell_data_func( fooRenderer, CB_FUNCTION( foocolData ) );
fooRenderer.property_sensitive() = true; // done by default
fooRenderer.signal_toggled().CONNECT( foocolToggled );
}
ExampleWindow::foocol::~foocol( )
{
std::cout << "foocol destructor " << this << "\n";
}
ExampleWindow::foocol::foocol( const ExampleWindow::foocol& copyMe )
: test(copyMe.test)
{
std::cout << "foocol copy constructor " << this << "\n";
}
ExampleWindow::foocol&
ExampleWindow::foocol::operator=( const ExampleWindow::foocol& copyMe )
{
std::cout << "assignement " << this << " = " << ©Me << "\n";
return *this;
}
/********* SIGNALS ******/
void
ExampleWindow::foocol::foocolData( Gtk::CellRenderer* renderer
, const Gtk::TreeModel::iterator&
iter )
{
std::cout << "foocolData " << this << "\n";
}
void
ExampleWindow::foocol::foocolToggled( const Glib::ustring& path )
{
std::cout << "foocolToggled " << this << "\n";
}
main.cc :
#include <iostream>
#include "examplewindow.hh"
#include <gtkmm/application.h>
int main( int argc
, char *argv[] )
{
Glib::RefPtr<Gtk::Application> app
= Gtk::Application::create( argc, argv
, "org.gtkmm.example" );
ExampleWindow window;
//Shows the window and returns when it is closed.
return app->run( window );
}
在 linux 上编译:
g++ examplewindow.cc main.cc `pkg-config gtkmm-3.0 --cflags --libs` -std=c++11
在 windows 上编译:
我不是种族主义者,我只是不知道如何在 windows 上编译。
截图:
问题:
好的,正如您所看到的,我花了一些时间来为我的问题举一个很好的例子。在屏幕截图上,您可以看到一个名为 foocol
的列,您可以在其中看到一个切换按钮,在左侧,您可以看到一个名为 model.mcolfoocol
.
第二列是我的问题所在,我根本看不到切换。我不知道为什么,我花了好几个小时都没能解决这个问题...
两列相同,不同的结果来自作为列添加的一列,而第二列(不起作用的列)是通过 Gtk::TreeModel::ColumnRecord
添加的。当然要用第二种方法了...
最好在我添加 // XXX
的行添加注释,这样控制台中的所有消息都会与问题相关。
可能的输出:
foocol constructor 0xbfda6e70
(a.out:12545): Gtk-CRITICAL **: gtk_cell_layout_add_attribute: assertion 'column >= 0' failed
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocolData 0xbfda6e70
foocol destructor 0xbfda6e70
不幸的是,我不知道如何调试使用多个库的程序。我什至不确定我的计算机是否有足够的内存来执行此操作...
真心觉得gtkmm这部分不直观...
您可能不想使用 ExampleWindow::foocal 作为模型支持类型(在 Gtk::TreeModelColumn
我不确定您的意图(您为什么不只使用 TreeModelColumn
examplewindow.h 变化
//My column class foocol - : public Gtk::TreeView::Column + : public Gtk::TreeView::Column, public Gtk::TreeModelColumn<bool> { ... - ModelColumns(void){ add(m_col_id); add(m_col_name); } + ModelColumns(void){ add(m_col_id); add(m_col_name); add (m_col_foocol); } ... - Gtk::TreeModelColumn<ExampleWindow::foocol> m_col_foocol; + foocol m_col_foocol;
examplewindow.cc
- m_TreeView.append_column( "model.m_col_foocol", m_Columns.m_col_foocol ); + m_TreeView.append_column( m_Columns.m_col_foocol );