How to pass parameters via contextmenu addActions() ?
-
wrote on 26 Jan 2022, 05:56 last edited by
I am trying to find a way to pass some parameters to a slot but am unable to do so, any suggestions?
I am getting the follow errors
QObject::connect: Incompatible sender/receiver arguments QAction::triggered(bool) --> WorldGraphicsView::contextMenuHandler(QString,QString) QObject::connect: Incompatible sender/receiver arguments QAction::triggered(bool) --> WorldGraphicsView::contextMenuHandler(QString,QString)
Full source code on github.
Header
#pragma once #include <QGraphicsView> #include <QMenu> class WorldGraphicsView: public QGraphicsView { Q_OBJECT public: explicit WorldGraphicsView(QWidget *parent = 0); ~WorldGraphicsView(); virtual void contextMenuEvent(QContextMenuEvent *event) override; private: QMenu* _contextMenu; private slots: void contextMenuHandler(QString parameter1, QString parameter2); };
Source
#include "WorldGraphicsView.h" #include <QContextMenuEvent> #include <QDebug> WorldGraphicsView::WorldGraphicsView(QWidget *parent) : QGraphicsView(parent) { _contextMenu = new QMenu(this); QString p1; QString p2; p1 = "hello"; p2 = "world"; QAction* communications = _contextMenu->addAction("communications",this,SLOT(contextMenuHandler(QString,QString))); p1 = "star"; p2 = "war"; QAction* transport = _contextMenu->addAction("transport",this,SLOT(contextMenuHandler(QString,QString))); } WorldGraphicsView::~WorldGraphicsView() { } void WorldGraphicsView::contextMenuEvent(QContextMenuEvent *event) { qDebug() << "WorldGraphicsView::contextMenuEvent"; _contextMenu->exec(event->globalPos()); } void WorldGraphicsView::contextMenuHandler(QString parameter1, QString parameter2) { }
-
Use a lambda as slot.
-
Use a lambda as slot.
wrote on 26 Jan 2022, 16:41 last edited by@Christian-Ehrlicher said in How to pass parameters via contextmenu addActions() ?:
Use a lambda as slot.
My attempt to use lambda to replace the slot and reading the link, I tried the following but it does not compile
WorldGraphicsView::WorldGraphicsView(QWidget *parent) : QGraphicsView(parent) { _contextMenu = new QMenu(this); QString p1; QString p2; p1 = "hello"; p2 = "world"; QAction* communications = _contextMenu->addAction("communications",this, [=](QString v1, QString v2) { this->contextMenuHandler( p1, p2 ); } ); }
Compilation error log
[ 42%] Building CXX object contextmenu/CMakeFiles/cm.dir/WorldGraphicsView.cpp.o In file included from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtGui/qtguiglobal.h:43:0, from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtWidgets/qtwidgetsglobal.h:43, from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtWidgets/qgraphicsview.h:43, from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtWidgets/QGraphicsView:1, from /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.h:3, from /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.cpp:1: /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qobject.h: In instantiation of ‘static typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType) [with Func1 = void (QAction::*)(bool); Func2 = WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)>; typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type = QMetaObject::Connection; typename QtPrivate::FunctionPointer<Func>::Object = QAction]’: /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtWidgets/qmenu.h:106:9: required from ‘typename std::enable_if<((! std::is_same<const char*, Func1>::value) && QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value), QAction*>::type QMenu::addAction(const QString&, const Obj*, Func1, const QKeySequence&) [with Obj = WorldGraphicsView; Func1 = WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)>; typename std::enable_if<((! std::is_same<const char*, Func1>::value) && QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value), QAction*>::type = QAction*]’ /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.cpp:17:4: required from here /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qobject.h:328:9: error: static assertion failed: Signal and slot arguments are not compatible. Q_STATIC_ASSERT_X((FunctorArgumentCount >= 0), ^ In file included from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qobjectdefs.h:50:0, from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qmetatype.h:50, from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtWidgets/qgraphicsview.h:44, from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtWidgets/QGraphicsView:1, from /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.h:3, from /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.cpp:1: /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qobjectdefs_impl.h: In instantiation of ‘struct QtPrivate::FunctorReturnType<WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)>, QtPrivate::List<> >’: /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qobject.h:331:158: required from ‘static typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType) [with Func1 = void (QAction::*)(bool); Func2 = WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)>; typename std::enable_if<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1), QMetaObject::Connection>::type = QMetaObject::Connection; typename QtPrivate::FunctionPointer<Func>::Object = QAction]’ /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtWidgets/qmenu.h:106:9: required from ‘typename std::enable_if<((! std::is_same<const char*, Func1>::value) && QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value), QAction*>::type QMenu::addAction(const QString&, const Obj*, Func1, const QKeySequence&) [with Obj = WorldGraphicsView; Func1 = WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)>; typename std::enable_if<((! std::is_same<const char*, Func1>::value) && QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value), QAction*>::type = QAction*]’ /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.cpp:17:4: required from here /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qobjectdefs_impl.h:371:78: error: no matching function for call to ‘WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)>::operator()()’ typedef decltype(dummy<Functor>().operator()((dummy<ArgList>())...)) Value; ^~~~~ /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.cpp:16:31: note: candidate: WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)> [=](QString v1, QString v2 ) { this->contextMenuHandler( p1, p2 ); } ^ /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.cpp:16:31: note: candidate expects 2 arguments, 0 provided In file included from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qobjectdefs.h:50:0, from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qmetatype.h:50, from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtWidgets/qgraphicsview.h:44, from /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtWidgets/QGraphicsView:1, from /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.h:3, from /home/nyue/projects/Qt/QtQuestions/QtQuestions_git/Qt5/contextmenu/WorldGraphicsView.cpp:1: /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qobjectdefs_impl.h:451:18: error: ‘QtPrivate::QFunctorSlotObject<Func, N, Args, R>::QFunctorSlotObject(Func) [with Func = WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)>; int N = 0; Args = QtPrivate::List<>; R = void]’, declared using local type ‘WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)>’, is used but never defined [-fpermissive] explicit QFunctorSlotObject(Func f) : QSlotObjectBase(&impl), function(std::move(f)) {} ^~~~~~~~~~~~~~~~~~ /home/nyue/systems/Qt/5.14.2/5.14.2/gcc_64/include/QtCore/qobjectdefs_impl.h:451:18: warning: ‘QtPrivate::QFunctorSlotObject<Func, N, Args, R>::QFunctorSlotObject(Func) [with Func = WorldGraphicsView::WorldGraphicsView(QWidget*)::<lambda(QString, QString)>; int N = 0; Args = QtPrivate::List<>; R = void]’ used but never defined contextmenu/CMakeFiles/cm.dir/build.make:103: recipe for target 'contextmenu/CMakeFiles/cm.dir/WorldGraphicsView.cpp.o' failed make[2]: *** [contextmenu/CMakeFiles/cm.dir/WorldGraphicsView.cpp.o] Error 1 CMakeFiles/Makefile2:98: recipe for target 'contextmenu/CMakeFiles/cm.dir/all' failed make[1]: *** [contextmenu/CMakeFiles/cm.dir/all] Error 2 Makefile:110: recipe for target 'all' failed make: *** [all] Error 2
-
Where should the two parameters for your lambda come from? The slot must have the same (or less) number of arguments as the signal, in your case it's 1 or 0 since QAction::triggered() only has bool as a parameter.
-
wrote on 26 Jan 2022, 19:32 last edited by
I got it working.
WorldGraphicsView::WorldGraphicsView(QWidget *parent) : QGraphicsView(parent) { _contextMenu = new QMenu(this); QString p1; QString p2; p1 = "hello"; p2 = "world tomorrow"; bool s = true; QAction* communications = _contextMenu->addAction("communications"); connect(communications, &QAction::triggered, this, [this, v1=p1, v2=p2]{ contextMenuHandler(v1,v2); }); }
-
I got it working.
WorldGraphicsView::WorldGraphicsView(QWidget *parent) : QGraphicsView(parent) { _contextMenu = new QMenu(this); QString p1; QString p2; p1 = "hello"; p2 = "world tomorrow"; bool s = true; QAction* communications = _contextMenu->addAction("communications"); connect(communications, &QAction::triggered, this, [this, v1=p1, v2=p2]{ contextMenuHandler(v1,v2); }); }
@nicholas_yue said in How to pass parameters via contextmenu addActions() ?:
[this, v1=p1, v2=p2]{
Why do you want to rename them? A simple [this, p1, p2] is enough.
1/6