我必须创建2个自定义事件。 我按照这个链接&我的代码: - Is there a cleaner way to register Qt custom events?
这是创建&的正确方法吗?发布&将一些数据(Qstring)传递给自定义事件?
=============================================== ============
根据Kuba Ober sugession编辑代码:---
Mainwindow.h: -
UpdateEvent *myUpdateEvent ;
ClearEvent *myClearEvent ;
Mainwindow.c:---
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
i =0;
myUpdateEvent = new UpdateEvent("hello");
myClearEvent = new ClearEvent("bye");
QCoreApplication::postEvent(this, myUpdateEvent);
QCoreApplication::postEvent(this, myClearEvent);
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
qDebug() << "oo";
if (UpdateEvent::is(event)) {
UpdateEvent *tempUpdateEvent = static_cast<UpdateEvent *>(event);
qDebug() << tempUpdateEvent->value();
}
else if (ClearEvent::is(event)) {
ClearEvent *tempClearEvent = static_cast<ClearEvent *>(event);
qDebug() << tempClearEvent->value();
}
return true;
}
event.h文件: -
template <typename T> class StringEvent : public QEvent
{
QString m_str;
public:
explicit StringEvent(const QString val) : QEvent(staticType()), m_str(val)
{
}
QString setvalue(QString val)
{
m_str = val;
}
QString value() const
{
return m_str;
}
static QEvent::Type staticType()
{
static int type = QEvent::registerEventType();
return static_cast<QEvent::Type>(type);
}
static bool is(const QEvent * ev)
{
return ev->type() == staticType();
}
};
class UpdateEvent : public StringEvent<UpdateEvent>
{
public:
explicit UpdateEvent(QString val): StringEvent(val)
{
}
};
class ClearEvent : public StringEvent<ClearEvent>
{
public:
explicit ClearEvent(QString val): StringEvent(val)
{
}
};
为什么不触发eventFilter?我无法在postevent上看到调试消息?
答案 0 :(得分:0)
我只能评论您的事件实现的代码气味,因为此时不清楚为什么需要将事件发送到窗口中的编辑控件。后者是糟糕的设计。
你的活动课程不必要地复杂化。您应该在构建期间在事件内部设置所有值,然后应该可以通过只读访问器访问它们。额外的事件类型似乎也是一个不必要的噱头。
以下是我如何使用metafactory模式(我刚刚创造的名称,或许它有一个更好/现有的名称?)。这解决了需要显式派生类构造函数注入的问题。
为了便于理解,我将metafactory分成了小组成部分。
// A type-identifier-generating wrapper for events
template <typename D> class EventWrapper : public QEvent {
public:
EventWrapper() : QEvent(staticType()) {}
static QEvent::Type staticType() {
static QEvent::Type type = static_cast<QEvent::Type>(registerEventType());
return type;
}
static bool is(const QEvent * ev) { return ev->type() == staticType(); }
static D* cast(QEvent * ev) { return is(ev) ? static_cast<D*>(ev) : 0; }
};
// The generic event metafactory for C++98 (doesn't need C++11)
template <typename D, template <typename> class Carrier> class EventMF {
class EventFwd;
class Final;
class FinalWrapper : public EventWrapper<EventFwd>, public virtual Final {};
public:
// EventFwd is a class derived from Event. The EventWrapper's cast()
// will cast to a covariant return type - the derived class. That's OK.
typedef Carrier<FinalWrapper> Event;
private:
class EventFwd : public Event {};
class Final {
friend class FinalWrapper;
friend class Carrier<FinalWrapper>;
private:
Final() {}
Final(const Final &) {}
};
};
// A string carrier
template <typename B> class StringData : public B {
QString m_str;
public:
explicit StringData(const QString & str) : m_str(str) {}
QString value() const { return m_str; }
};
// A string event metafactory
template <typename D> class StringEventMF : public EventMF<D, StringData> {};
class Update : public EventMF<Update, StringData> {}; // using generic metafactory
class Clear : public StringEventMF<Clear> {}; // using specific metafactory
#if 0
// This should fail at compile time as such derivation would produce classes with
// duplicate event types. That's what the Final class was for in the matafactory.
class Error : public Update::Event { Error() : Update::Event("") {} };
#endif
int main(int, char**)
{
// Test that it works as expected.
Update::Event update("update");
Clear::Event clear("clear");
Q_ASSERT(Update::Event::staticType() != Clear::Event::staticType());
Q_ASSERT(Update::Event::staticType() == Update::Event::cast(&update)->staticType());
qDebug() << Update::Event::cast(&update)->value();
Q_ASSERT(Update::Event::cast(&clear) == 0);
qDebug() << Clear::Event::cast(&clear)->value();
Q_ASSERT(Clear::Event::cast(&update) == 0);
}
Metafactory::Event
类是自QEvent
派生的自定义事件类。
Update :: Event的类层次结构如下所示(从最少派生类到最派生类):
EventWrapper<EventMF<...>::EventFwd>
,EventMF<...>::Final
(多重继承)EventMF<Update, StringData<Update>>::FinalWrapper
StringData<Update> = EventMF<Update, StringData<Update>>::Event
EventMF<...>
是EventMF<Update, StringData<Update>
的缩写。
行Update::Event update("update")
构造一个自定义的字符串携带事件实例,上面列表中从最后一个到第一个调用构造函数。
由于EventMF<...>
是仅在编译时起作用的元数据,因此完全不需要在运行时存在其实例。因此永远不会调用EventMF<...>::EventMF
构造函数。您可以通过删除构造函数来强制执行此不变量(将其声明为C ++ 98的私有)。
事件处理程序中的用法如下所示:
void MainWindow::customEvent(QEvent *event)
{
...
if (Update::Event::is(event)) {
qDebug() << Update::Event::cast(event)->value();
...
}
else if (Clear::Event::is(event)) {
...
}
...
}