类似策略模式,Qt实现动态函数调用
#ifndef LISTBASEWIDGET_H
#define LISTBASEWIDGET_H
#include <QWidget>
#include <QListWidget>
#include <QList>
static const int MAX_PTR=10;
//基类
class BaseWidget:public QWidget
{
Q_OBJECT
public:
explicit BaseWidget(QWidget *parent=0);
virtual ~BaseWidget(){
delete m_listWidget;
m_listWidget=NULL;
}
virtual void addItem(QWidget *parent,const QString& itemnamestr);
virtual void trigger(const int index)=0;
protected:
bool eventFilter(QObject *, QEvent *);
private:
QListWidget *m_listWidget;
};
//
class ListWidgetOne:public BaseWidget{
Q_OBJECT
public:
explicit ListWidgetOne(QWidget *parent=0);
~ListWidgetOne(){}
virtual void trigger(const int index);
private:
void redItemFun();
void greenItemFun();
typedef void (ListWidgetOne::*funPtr)(void);
funPtr funPtrArray[MAX_PTR];
// QList<funPtr> funPtrList;
};
#endif // LISTBASEWIDGET_H
#include "listbasewidget.h"
#include <QList>
#include <QDebug>
#include <QMouseEvent>
#include <QListWidget>
#include <QHBoxLayout>
BaseWidget::BaseWidget(QWidget *parent):QWidget(parent),
m_listWidget(new QListWidget(this))
{
QHBoxLayout *layout=new QHBoxLayout;
layout->addWidget(m_listWidget);
setLayout(layout);
m_listWidget->viewport()->installEventFilter(this);
}
void BaseWidget::addItem(QWidget *parent, const QString &itemnamestr)
{
if(parent==NULL)
return;
m_listWidget->addItem(new QListWidgetItem(itemnamestr));
}
bool BaseWidget::eventFilter(QObject *o, QEvent *e)
{
if (o == m_listWidget->viewport()) {
if (e->type() == QEvent::MouseButtonDblClick) {
QMouseEvent *me = static_cast<QMouseEvent*>(e);
trigger(m_listWidget->currentRow());
return true;
} else {
return false;
}
} else {
// pass the event on to the parent class
return QWidget::eventFilter(o, e);
}
}
void ListWidgetOne::redItemFun()
{
qDebug()<<"--void ListWidgetOne::redItemFun()";
}
void ListWidgetOne::greenItemFun()
{
qDebug()<<"--void ListWidgetOne::greenItemFun()";
}
ListWidgetOne::ListWidgetOne(QWidget *parent)
{
for(int i=0;i<5;++i)
addItem(this,QString::number(i));
#if 1
funPtrArray[0]=&ListWidgetOne::redItemFun;
funPtrArray[1]=&ListWidgetOne::greenItemFun;
#endif
#if 0
funPtrList.append(&ListWidgetOne::redItemFun);
funPtrList.append(&ListWidgetOne::greenItemFun);
#endif
}
void ListWidgetOne::trigger(const int index)
{
#if 1
funPtr ptr=funPtrArray[index];
if(ptr!=NULL)
(this->*ptr)();
#endif
#if 0
if(index>=funPtrList.size())
return ;
funPtr ptr=funPtrList.value(index);
(this->*ptr)();
#endif
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ListWidgetOne *l=new ListWidgetOne;
l->show();
return a.exec();
}
1 如果想简化某些界面创建工作,并且不用建立众多的信号槽。
2 熟悉函数指针的使用方法。
3 代码重用。
4 一般情况还是使用信号槽更加思路清楚。
5 注意事件过滤器要安装在QListWidget的viewport上面。