我正在使用GTK + 3.0编写C ++程序。无论如何,我认为这个问题可能适用于任何使用事件/信号的框架。
我有一个容器类,比如containerClass
和一个子类,比如childClass
。 childClass
对象child
包含在containerClass
对象container
中。
编写child
对象以修改某些内容的属性。为此目的,它有GtkEntry
,GtkButton
等等。当我单击“保存按钮”时,会引发一个事件。
此事件必须由container
对象处理,因为container
在某种程度上与数据库接口。
此后,您会找到我正在使用的解决方案:
// Child class
class childClass {
void setClickHandler_External(void (*extFun)(string property), void *);
void (*clickHandler_External)(string, void *);
void *clickHandler_External_Data;
static void buttonClicked(GtkWidget *widget, void *data);
}
void childClass::setClickHandler_External(void (*extFun)(string), void *data) {
// Set the external event handler
clickHandler_External = extFun;
clickHandler_External_Data = data;
}
void childClass::buttonClicked(GtkWidget *widget, void *data) {
childClass *m = (childClass *)data;
// Call the external event handler
m->clickHandler_External(property, m->clickHandler_External_Data);
}
// Container Class
class containerClass {
childClass child;
static void clickHandler(string property, void *data);
}
containerClass::containerClass() {
// Set the event handler
child.setClickHandler_External((void(*)(string))&(this->clickHandler), (void *)this);
}
void containerClass::clickHandler(string property, void *data) {
// Event handler in the upper class
containerClass *m = (containerClass *)data;
//FINALLY, DO THE JOB WITH PROPERTY!!!
}
这很好用并完成工作。无论如何,我想知道是否有更智能和更清晰的方法来实现相同的目标,可能没有使用指向静态函数的指针,或者通过定义某种类型的模式,每次我需要具有相同的机制时重用。
提前致谢
答案 0 :(得分:2)
Gtkmm使用sigc ++库来为您处理所有这些。没有必要自己写。
文档链接:
所以,在这种情况下,我会使用像
这样的东西button.signal_clicked().connect(sigc::mem_fun(container, &containerClass::clickHandler));
同时确保containerClass::clickHander
具有适当数量的参数。
答案 1 :(得分:1)
我的第一个建议是使用使用模板来改善你正在做的事情的类型安全性:
template< class ParamType >
void childClass::setClickHandler_External(void (*extFun)(string, ParamType *),
ParamType *data)
{
// Set the external event handler
clickHandler_External = (void ()(string,void*))extFun;
clickHandler_External_Data = (void*)data;
}
然后您可以简化containerClass实现:
// Container Class
class containerClass {
childClass child;
static void clickHandler(string property, containerClass *data);
}
containerClass::containerClass() {
// Set the event handler
child.setClickHandler_External(&containerClass::clickHandler, this);
}
void containerClass::clickHandler(string property, containerClass *data) {
//FINALLY, DO THE JOB WITH PROPERTY!!!
}
虽然很好地清理了实现,但是从所有容器实现者中删除了显式的转换,但这并非如此。关键是要防止你将错误的指针传递给setClickHandler_External,在调度事件时导致后端发生崩溃。
我的下一步将从实施中进一步了解,但需要更多有关您实际行动的细节。根据您的需求进行调查: