C++, emit signal from custom eventfilter failed
-
I have a question about qt signal/slot and custom eventfilter.
usually, the default eventfilter is looks like "xxx->installEventFilter(this)".
I create a new class about custom eventfilter. It works well.
but, when I want emit a signal from it, it failed, signal/slot not work.bellow is some main codes about this:
PlotsView.cpp
void PlotsView::createPlot() { std::map<std::string, std::string> param_map = { {"tickerstr", 1234} }; QHBoxLayout *candleplotlay = new QHBoxLayout(); PlotCreatorDF customcandle; QCustomPlot *candleplot; candleplot = customcandle.setupCandlestick(param_map); QObject::connect(&customcandle, SIGNAL(atesty(int)), this, SLOT(atestyy(int))); plotcontainerlay->addWidget(candleplot); } void PlotsView::atestyy(int x) { qDebug() << "[CandleNewSecurity_List>>atestyy] x: " << x; }PlotCreatorDF.h
class PlotCreatorDF : public QWidget { Q_OBJECT public: explicit PlotCreatorDF(QWidget *parent = nullptr); ~PlotCreatorDF(); public slots: void atestz(int x); signals: void atesty(int x); };PlotCreatorDF.cpp
#include "PlotCreatorDF.h" #include "qcustomplot.h" #include "Plot/ploteventfilter.h" PlotCreatorDF::PlotCreatorDF(QWidget *parent) : QWidget(parent) { } PlotCreatorDF::~PlotCreatorDF() { qDebug()<<__LINE__<<__FUNCTION__; } QCustomPlot* PlotCreatorDF::setupCandlestick(std::map<std::string, std::string> param_map) { QCustomPlot *daily_plot = new QCustomPlot(); daily_plot->setObjectName("test"); //: PlotEventFilter *customfilter = new PlotEventFilter(); daily_plot->installEventFilter(customfilter); connect(customfilter, SIGNAL(atestx(int)), this, SIGNAL(atesty(int))); connect(customfilter, SIGNAL(atestx(int)), this, SLOT(atestz(int))); return daily_plot; } void PlotCreatorDF::atestz(int x) { qDebug() << "[PlotCreatorDF>>atestz] x: " << "x"; // }customeventfilter.h
#ifndef CUSTOMENTFILTER_H #define CUSTOMENTFILTER_H #include <QWidget> namespace Ui { class CustomEventFilter; } class CustomEventFilter : public QWidget { Q_OBJECT public: explicit CustomEventFilter(QWidget *parent = nullptr); ~CustomEventFilter(); bool eventFilter(QObject *obj, QEvent *qevt); signals: void atestx(int x); private: }; #endif // PLOTEVENTFILTER_Hcustomeventfilter.cpp
#include "customeventfilter.h" CustomEventFilter::CustomEventFilter(QWidget *parent) : QWidget(parent){} CustomEventFilter::~CustomEventFilter() { qDebug()<<__LINE__<<__FUNCTION__; } bool CustomEventFilter::eventFilter(QObject *obj, QEvent *qevt){ if (qevt->type() == QEvent::MouseButtonPress) { //MouseButtonPress qDebug() << "[CustomEventFilter>>eventFilter] mouse clicked ... "; emit atestx(123); } return false; }The connection seems failed to create the connection, and the slot function atestz not work.
Can anyone help me, why and how, thanks!
I have to say all the connections in the code not work.
It seems that any signal can't be sent from "CustomEventFilter".
-
I can't understand which } effect the connect. sorry, I am trying to understanding what you said.
I think you found the problem correctly. do you mean the "return daily_plot" throw the connections away?
so, how can I emit a signal from my custom eventfileter?@xkungfu
Your problem is not a custom event filter and emitting of signals. That will work. Your code is faulty.You need to understand object lifetimes and local variables. Your
PlotCreatorDF customcandleis a local variable. You use that as thethisin yourconnect()s But as soon as methodPlotsView::createPlot()exits thePlotCreatorDF customcandleis destroyed. Its slots cannot be called, so you don't see the signal (correctly emitted) any longer. This is where your problem lies.Qt is clever enough to see when
customcandlegoes out of scope and gets destroyed. It disconnects any signals connected to its slots, so yourconnect()s get removed. This is why the slots don't get called but you don't get an error.Change
PlotCreatorDF customcandleover toPlotCreatorDF *customcandle = new PlotCreatorDF()and your code will work/signals fired/slots called. Of course you then have to think about when it should now get destroyed, to avoid a leak.You already do this in
PlotEventFilter *customfilter = new PlotEventFilter();, and likely that leaks too? -
I have a question about qt signal/slot and custom eventfilter.
usually, the default eventfilter is looks like "xxx->installEventFilter(this)".
I create a new class about custom eventfilter. It works well.
but, when I want emit a signal from it, it failed, signal/slot not work.bellow is some main codes about this:
PlotsView.cpp
void PlotsView::createPlot() { std::map<std::string, std::string> param_map = { {"tickerstr", 1234} }; QHBoxLayout *candleplotlay = new QHBoxLayout(); PlotCreatorDF customcandle; QCustomPlot *candleplot; candleplot = customcandle.setupCandlestick(param_map); QObject::connect(&customcandle, SIGNAL(atesty(int)), this, SLOT(atestyy(int))); plotcontainerlay->addWidget(candleplot); } void PlotsView::atestyy(int x) { qDebug() << "[CandleNewSecurity_List>>atestyy] x: " << x; }PlotCreatorDF.h
class PlotCreatorDF : public QWidget { Q_OBJECT public: explicit PlotCreatorDF(QWidget *parent = nullptr); ~PlotCreatorDF(); public slots: void atestz(int x); signals: void atesty(int x); };PlotCreatorDF.cpp
#include "PlotCreatorDF.h" #include "qcustomplot.h" #include "Plot/ploteventfilter.h" PlotCreatorDF::PlotCreatorDF(QWidget *parent) : QWidget(parent) { } PlotCreatorDF::~PlotCreatorDF() { qDebug()<<__LINE__<<__FUNCTION__; } QCustomPlot* PlotCreatorDF::setupCandlestick(std::map<std::string, std::string> param_map) { QCustomPlot *daily_plot = new QCustomPlot(); daily_plot->setObjectName("test"); //: PlotEventFilter *customfilter = new PlotEventFilter(); daily_plot->installEventFilter(customfilter); connect(customfilter, SIGNAL(atestx(int)), this, SIGNAL(atesty(int))); connect(customfilter, SIGNAL(atestx(int)), this, SLOT(atestz(int))); return daily_plot; } void PlotCreatorDF::atestz(int x) { qDebug() << "[PlotCreatorDF>>atestz] x: " << "x"; // }customeventfilter.h
#ifndef CUSTOMENTFILTER_H #define CUSTOMENTFILTER_H #include <QWidget> namespace Ui { class CustomEventFilter; } class CustomEventFilter : public QWidget { Q_OBJECT public: explicit CustomEventFilter(QWidget *parent = nullptr); ~CustomEventFilter(); bool eventFilter(QObject *obj, QEvent *qevt); signals: void atestx(int x); private: }; #endif // PLOTEVENTFILTER_Hcustomeventfilter.cpp
#include "customeventfilter.h" CustomEventFilter::CustomEventFilter(QWidget *parent) : QWidget(parent){} CustomEventFilter::~CustomEventFilter() { qDebug()<<__LINE__<<__FUNCTION__; } bool CustomEventFilter::eventFilter(QObject *obj, QEvent *qevt){ if (qevt->type() == QEvent::MouseButtonPress) { //MouseButtonPress qDebug() << "[CustomEventFilter>>eventFilter] mouse clicked ... "; emit atestx(123); } return false; }The connection seems failed to create the connection, and the slot function atestz not work.
Can anyone help me, why and how, thanks!
I have to say all the connections in the code not work.
It seems that any signal can't be sent from "CustomEventFilter".
@xkungfu said in C++, emit signal from custom eventfilter failed:
{ PlotCreatorDF customcandle; ... QObject::connect(&customcandle, SIGNAL(atesty(int)), this, SLOT(atestyy(int))); }If this is supposed to work (fire signal to hit slot) for whatever you are asking about, it won't.
customcandlegoes out of scope at}so it will never emit any signals after that. Is this relevant to what you see?Since no
PlotCreatorDFinstance persists, thethisinPlotCreatorDF::setupCandlestick()connect(customfilter, SIGNAL(atestx(int)), this, SIGNAL(atesty(int))); connect(customfilter, SIGNAL(atestx(int)), this, SLOT(atestz(int)));means these slots get removed from being connected.
-
I can't understand which } effect the connect. sorry, I am trying to understanding what you said.
I think you found the problem correctly. do you mean the "return daily_plot" throw the connections away?
so, how can I emit a signal from my custom eventfileter? -
I can't understand which } effect the connect. sorry, I am trying to understanding what you said.
I think you found the problem correctly. do you mean the "return daily_plot" throw the connections away?
so, how can I emit a signal from my custom eventfileter?@xkungfu
Your problem is not a custom event filter and emitting of signals. That will work. Your code is faulty.You need to understand object lifetimes and local variables. Your
PlotCreatorDF customcandleis a local variable. You use that as thethisin yourconnect()s But as soon as methodPlotsView::createPlot()exits thePlotCreatorDF customcandleis destroyed. Its slots cannot be called, so you don't see the signal (correctly emitted) any longer. This is where your problem lies.Qt is clever enough to see when
customcandlegoes out of scope and gets destroyed. It disconnects any signals connected to its slots, so yourconnect()s get removed. This is why the slots don't get called but you don't get an error.Change
PlotCreatorDF customcandleover toPlotCreatorDF *customcandle = new PlotCreatorDF()and your code will work/signals fired/slots called. Of course you then have to think about when it should now get destroyed, to avoid a leak.You already do this in
PlotEventFilter *customfilter = new PlotEventFilter();, and likely that leaks too? -
@xkungfu
Your problem is not a custom event filter and emitting of signals. That will work. Your code is faulty.You need to understand object lifetimes and local variables. Your
PlotCreatorDF customcandleis a local variable. You use that as thethisin yourconnect()s But as soon as methodPlotsView::createPlot()exits thePlotCreatorDF customcandleis destroyed. Its slots cannot be called, so you don't see the signal (correctly emitted) any longer. This is where your problem lies.Qt is clever enough to see when
customcandlegoes out of scope and gets destroyed. It disconnects any signals connected to its slots, so yourconnect()s get removed. This is why the slots don't get called but you don't get an error.Change
PlotCreatorDF customcandleover toPlotCreatorDF *customcandle = new PlotCreatorDF()and your code will work/signals fired/slots called. Of course you then have to think about when it should now get destroyed, to avoid a leak.You already do this in
PlotEventFilter *customfilter = new PlotEventFilter();, and likely that leaks too?