Using QObject::conect in a static function
-
Hello.
I have an abstract base class and two derived classes. The base one has astatic QFileSystemWatcher
attribute so that all instances of the derived classes can watch one folder and one file. Then I made a function to activate this watching system (I can't do this in the constructor because I should be able to turn it off at some point and back on) and I thought that it should be astatic
function so it can be activated once for all derived classes. The problem is that when I do:connect(&watchDir, &QFileSystemWatcher::directoryChanged, this, &BaseClass::handleDirChanged); connect(&watchDir, &QFileSystemWatcher::fileChanged, this, &BaseClass::handleFileChanged);
I get
error: invalid use of 'this' outside of a non-static member function
. I tried removingthis
but I get errors at compilation saying that there is no matching function for such a call ofQObject::connect
.connect(&watchDir, &QFileSystemWatcher::directoryChanged, &BaseClass::handleDirChanged); connect(&watchDir, &QFileSystemWatcher::fileChanged, &BaseClass::handleFileChanged);
What does this happen and what should I do?
-
@diego-qt said in Using QObject::conect in a static function:
What does this happen and what should I do?
You can only connect a signal to a slot. A slot has to be a non static method (or a lambda function). In a static method there is no "this" because there is no instance. The connections should be done by the instances of the derived classes. Or you can keep a static member (vector or list) containing pointers to all of your instances and then iterate over it to connect all of them.
You should keep in mind that all instances will watch exactly the same file/folder because they share same watcher! Are you sure this is what you want? Or should different instances be able to watch different files/directories?
-
@jsulm I already have a vector of pointers to all the derived classes instances so the idea of the connection wouldn't be a problem. But now that I think about it, this may not be a such great idea. Maybe I should create a new class that will be in charge of reading the file and passing the correct data to the derived classes.
I would have liked that
handleDirChanged
andhandleFileChanged
read the first character of every new line in the watched file whenever it is modified (because this character will determined which derived class needs the information, example below) and send the rest of the line to the correct object.0 wcsfe2xe21xf... 1 fewef2eq35d535d... 1 d5d43zq1d35z... 0 zdz3d5qz351... 1 defe32f1e3f51e...
-
@jsulm said in Using QObject::conect in a static function:
You should keep in mind that all instances will watch exactly the same file/folder because they share same watcher! Are you sure this is what you want? Or should different instances be able to watch different files/directories?
There is only one file to watch and all the data for all derived classes will be in it. So I need to extract the first character of every new line.
-
@diego-qt
I have to say This approach may be flaky/not robust for a variety of reasons.I will just ask briefly: from what i can see/guess about what you are doing did you consider a socket or named pipe as your "channel of communication" between processes instead of a physical file?
-
connect(&watchDir, &QFileSystemWatcher::directoryChanged, &BaseClass::handleDirChanged); connect(&watchDir, &QFileSystemWatcher::fileChanged, &BaseClass::handleFileChanged);
try to remove & in &BaseClass::handleDirChanged
A slot has to be a non static method
Wrong, i'm using a static method in one of my class:
// static method declaration in EventCenter class private slots: static void _observerDestroyed(QObject* o); // connection connect(observer,&QObject::destroyed,EventCenter::_observerDestroyed); // slot méthode static void EventCenter::_observerDestroyed(QObject *o) { EventCenter().removeObserver(o); }
-
@mpergand said in Using QObject::conect in a static function:
try to remove & in &BaseClass::handleDirChanged
That is interesting, and I haven't seen before! Do you have a C++ reference for this I could read up on, please? It sounds to me like yet another C++ "non-customary/overloaded" use of
&
to me :) -
@mpergand
Hmm, I need more than that! :)I have gone looked at https://woboq.com/blog/new-signals-slots-syntax-in-qt5.html, sub-topic Connecting to any function. So I do see where it comes from. But that doesn't explain anything from the C++ side, just says how you can use it in Qt. But ultimately this must be using behaviour from C++.
P.S.
I'll just say this: if you look at https://stackoverflow.com/questions/48164489/how-to-use-static-slot-function-in-qt, including the various comments, you get some people claiming it does not work without the&
and must nonetheless have the&
, and some the other way round. And similar in https://stackoverflow.com/questions/45439600/qt-sending-signal-to-static-slot-in-another-class. Extremely confusing! -
@JonB said in Using QObject::conect in a static function:
I will just ask briefly: from what i can see/guess about what you are doing did you consider a socket or named pipe as your "channel of communication" between processes instead of a physical file?
I honestly don't know what that is, sorry ^^' but I can look into it to see if it is a better approach than my initial idea.
I have to admit it seemed easy at the beginning but it turned out to be hard to develop. -
@diego-qt said in Using QObject::conect in a static function:
I have to admit it seemed easy at the beginning but it turned out to be hard to develop.
This is called "programming" ;-) It's also why we're all underpaid....
I don't want to make you rewrite the whole thing. I'm also not claiming I have the time to digest or advise on a complete design methodology.
But you might like to say a few words about what this file is for, who writes to it when, what processes you seem to have which need to communicate?
"Sockets" and "named pipes" are one from of "IPC" --- InterProcess Communication. You have a "sender" and a "receiver". You are kind of using your file for that, I think. One difference is that there is no "going back and overwriting" --- you don't usually need that for messaging --- which you seem to be doing. Sockets also work across machines whereas
QFileWatcher
basically does not, which may or may not be relevant to your requirement.Anyway, like I said it's a big subject, and I'm not volunteering to write it for you, so up to you --- you might prefer to stay with what you are doing now since you have existing code.