Reputation: 363
In my Qt application I wish to be able to add a tab to a non-static QTabWidget
when the user presses a shortcut. Normally I would implement it like this:
File.addAction("Settings", openSettings, Qt::ALT + Qt::Key_S);
where File
is a QTabWidget
and openSettings
is a static method. The only issue with that is that it only works for static methods, and the issue with that is that I can't access a non-static variable in a static method. As such I figured that since Qt asks for the function to be a static function I can instantiate a static std::function<>
object as such:
static std::function<void(void)> openSettings_ = []() { openSettings; };
and call it as such
File.addAction("Settings", openSettings_, Qt::ALT + Qt::Key_S);
The issue with this is that it generates the error:
Error: invalid use of non-static member function 'void window::openSettings()'
My reasoning for this is that I am familiar with C and assumed that what Qt calls a functor is almost the same as a function pointer that pretty much is an object. As such, I assumed that if I were to instantiate a static object of type std::function
that pointed to / executed a non-static function I would get around this issue, which is clearly not the case. How would I go about doing this, seeing as my current thought process is wrong?
Upvotes: 0
Views: 1970
Reputation: 6430
First, the immediate error is raised because you're not actually calling the function. You must call it: openSettings();
.
However, this won't work. openSettings
is non-static member function. All such normal member functions take an implicit this
pointer to the object on which they're being invoked. This means that one cannot directly invoke the openSettings
function without an object on which to invoke it. But this
is not captured by the lambda you've written, meaning there's no such object.
This can be fixed by capturing this
in the lambda, such as auto openSettings_ = [this]() { this->openSettings(); }
;
But on the other hand, this function is acting like a slot. You should attach the signal you're interested in directly to the signal using the standard signal/slot syntax, rather than writing the separate functor. That would be something like this.
File.addAction("Settings", this, &(decltype(*this))::openSettings, Qt::ALT + Qt::Key_S);
(Note that I'm using decltype
because I'm not sure what type *this
is. You can substitute with the name of the class.)
Upvotes: 2