QMetaObject::invokeMethod and SLOT macro: No such method
-
Hi, and welcome!
@candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:
Are QMetaObject::invokeMethod and SLOT macro incompatible?
The
SLOT()
macro is for the old version ofQObject::connect()
. It is not forQMetaObject::invokeMethod()
. -
So this means I have to make a workaround if the string SLOT returned is the only piece of information I have?
-
@candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:
So this means I have to make a workaround if the string SLOT returned is the only piece of information I have?
Sounds like it.
How do you get the string returned by SLOT()?
-
Hi,
What the macro generates is however it's not literally what you pass in that is returned hence the error you got.
-
Here examples of some macros of mine:
#define InvokeLater(slot) QMetaObject::invokeMethod(this, #slot,Qt::QueuedConnection) #define InvokeLaterWithArg(slot,argType,arg) QMetaObject::invokeMethod(this, #slot,Qt::QueuedConnection,Q_ARG(argType,arg))
-
@candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:
Problem is that invokeMethod doesn't recognize what SLOT says.
I'm still trying to understand why this is a problem.
Can you please explain your use-case? How come the
SLOT()
string is the only piece of information that you have?Isn't it just a plain const char *?
Yes, it's a const char*, but it's in the wrong format for invokeMethod().
Anyway, my question was: How do you obtain your slot function name?
-
@JKSH Well, the scenario:
namespace Helper{ class QFileDialogSaveCanceller: public QObject{ Q_OBJECT public slots: void Cancel(void){ emit this->Cancelled(QString()); } signals: void Cancelled(const QString &empty); } void InvokeQFileDialogSave(QWidget *window, const char *slot/*void(const QString &)*/, .../*filters, default name & extension, etc*/){ QFileDialog *dlg=new QFileDialog();//Can't use the static getSaveFileName(), since I want the default extension auto-added QFileDialogSaveCanceller *canceller=new QFileDialogSaveCanceller; canceller->setParent(dlg); connect(canceller, SIGNAL(Cancelled(const QString &)), window, slot); connect(dlg, &QDialog::rejected, canceller, &QFileDialogSaveCanceller::Cancel); /*connect(dlg, &QDialog::rejected, [window](void)->void{ QMetaObject::invokeMethod(window, slot, Q_ARG(QString()));//No such method });*/ dlg->open(window, slot); } } class MainWindow: public QMainWindow{}; MainWindow mw; Helper::InvokeQFileDialogSave(&mw, SLOT(FileSelected(const QString &)), ...);
I'm just too lazy to template-ize the helper function, neither do I wanna write another "MainWindow::Cancelled(void)" slot to do the forwarding. Tried invokeMethod but no luck, thus this post.
-
@candy76041820 said in QMetaObject::invokeMethod and SLOT macro: No such method:
I'm just too lazy to template-ize the helper function, neither do I wanna write another "MainWindow::Cancelled(void)" slot to do the forwarding. Tried invokeMethod but no luck, thus this post.
That's an interesting setup.
You could use function pointers instead of strings:
using MySlot = void(QWidget::*)(const QString&); void InvokeQFileDialogSave(QWidget *window, MySlot slot) { auto dlg = new QFileDialog; auto canceller = new QFileDialogSaveCanceller; connect(canceller, &QFileDialogSaveCanceller::Cancelled, window, slot); connect(dlg, &QDialog::rejected, [window, slot] { (window->*slot)( QString() ); }); // ... }
Or, you could use string manipulation to find the slot name.
//Can't use the static getSaveFileName(), since I want the default extension auto-added
The
selectedFilter
parameter ofgetSaveFileName()
lets you set the default extension -
@JKSH Not applicable because I have other event sink classes.
Also, I use the SLOT string because (for the sake of keeping this post clear, I didn't demonstrate that) I have file-open scenarios too: void OnSingleSelect(const QString &file) and void OnMultiSelect(const QStringList &files). They don't share signatures, so either I need to template-ize (which doesn't work well w/ signals&slots), or to repeat and tweak the helper function.
Wait: will selectedFilter trigger setDefaultSuffix along with selectNameFilter? Didn't find evidence in the source tree.
Also again: Linux Qt 5.6.1, selectedFilter doesn't setDefaultSuffix. Call chain according to https://code.qt.io/cgit/qt/qtbase.git/plain/src/widgets/dialogs/qfiledialog.cpp :
QFileDialog::getSaveFileName -> QFileDialog::getSaveFileUrl -> QFileDialog::selectNameFilter -> QFileDialogPrivate::_q_useNameFilter, which doesn't seem to be doing the work (at least, in my case) after the user clicked OK.