Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QFileSystemWatcher doesnt send signals to my slots
Qt 6.11 is out! See what's new in the release blog

QFileSystemWatcher doesnt send signals to my slots

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 3 Posters 3.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    RetroZelda
    wrote on last edited by RetroZelda
    #1

    so I have a QFileSystemWatcher to essentially watch a folder for new files. I have connected to both "directoryChanged" and "fileChanged" slots but nothing happens when I create a new file, delete an existing file, or rename an existing file inside that directory.

    My basic setup is this:

    // exists in my header file:
    QFileSystemWatcher m_Watcher;
    
    // in my cpp constructor
    MyClass::MyClass() 
    : QObject(nullptr)
    , m_Watcher(this)
    {
    }
    
    // in my cpp:
    void WatchPath(const QString& path)
    {
        m_Watcher.addPath(path);
        connect(&m_Watcher, &QFileSystemWatcher::directoryChanged, this, &MyClass::on_directory_changed);
        connect(&m_Watcher, &QFileSystemWatcher::fileChanged, this, &MyClass::on_file_changed);
    }
    
    // and then my slot functions in my cpp
    void MyClass::on_directory_changed(const QString& path)
    {
        qDebug() << path << " changed";
        for(const QString& file : m_Watcher.files())
        {
            qDebug() << "on_directory_changed: " << file;
        }
    }
    
    void MyClass::on_file_changed(const QString& path)
    {
        qDebug() << path << " changed";
        for(const QString& file : m_Watcher.files())
        {
            qDebug() << "on_file_changed: " << file;
        }
    }
    
    // and then elsewhere not in a QObject
    MyClass* my_class = new MyClass();
    
    // and then in a widget somewhere else using the same MyClass pointer
    my_class->setParent(this);
    my_class->WatchPath("/full/system/path");
    

    I feel like im missing something, but based on the documentation i dont think I am. Since its dealing with filesystem, it might be relevant that im on debian(albeit i havnt updated in a while)

    $ uname -a
    Linux system76-debian 5.10.0-9-amd64 #1 SMP Debian 5.10.70-1 (2021-09-30) x86_64 GNU/Linux
    

    Any help would be appreciated.

    Thanks

    edit: i should note that "m_Watcher.addPath(path);" does return true

    JonBJ 1 Reply Last reply
    0
    • R RetroZelda

      so I have a QFileSystemWatcher to essentially watch a folder for new files. I have connected to both "directoryChanged" and "fileChanged" slots but nothing happens when I create a new file, delete an existing file, or rename an existing file inside that directory.

      My basic setup is this:

      // exists in my header file:
      QFileSystemWatcher m_Watcher;
      
      // in my cpp constructor
      MyClass::MyClass() 
      : QObject(nullptr)
      , m_Watcher(this)
      {
      }
      
      // in my cpp:
      void WatchPath(const QString& path)
      {
          m_Watcher.addPath(path);
          connect(&m_Watcher, &QFileSystemWatcher::directoryChanged, this, &MyClass::on_directory_changed);
          connect(&m_Watcher, &QFileSystemWatcher::fileChanged, this, &MyClass::on_file_changed);
      }
      
      // and then my slot functions in my cpp
      void MyClass::on_directory_changed(const QString& path)
      {
          qDebug() << path << " changed";
          for(const QString& file : m_Watcher.files())
          {
              qDebug() << "on_directory_changed: " << file;
          }
      }
      
      void MyClass::on_file_changed(const QString& path)
      {
          qDebug() << path << " changed";
          for(const QString& file : m_Watcher.files())
          {
              qDebug() << "on_file_changed: " << file;
          }
      }
      
      // and then elsewhere not in a QObject
      MyClass* my_class = new MyClass();
      
      // and then in a widget somewhere else using the same MyClass pointer
      my_class->setParent(this);
      my_class->WatchPath("/full/system/path");
      

      I feel like im missing something, but based on the documentation i dont think I am. Since its dealing with filesystem, it might be relevant that im on debian(albeit i havnt updated in a while)

      $ uname -a
      Linux system76-debian 5.10.0-9-amd64 #1 SMP Debian 5.10.70-1 (2021-09-30) x86_64 GNU/Linux
      

      Any help would be appreciated.

      Thanks

      edit: i should note that "m_Watcher.addPath(path);" does return true

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @RetroZelda
      Don't know if this helps, but your code looks OK in principle. (Though you are asking for both directoryChanged and fileChanged on the same path, I'm not sure whether both of those can be emitted.) I presume path refers to a directory.

      QFileSystemWatcher will have problems/won't work if the path is on a network (e.g. NFS), or if it is a mount point. But I don't suppose you're using either of those. Try it on your home directory, or one directory down, and do specify a full path for path.

      1 Reply Last reply
      1
      • AxelViennaA Offline
        AxelViennaA Offline
        AxelVienna
        wrote on last edited by
        #3

        You may have included the Q_OBJECT macro elsewhere in your code, I just don't see it here. You need it and you need to construct an instance of QApplication(int &, char **) (or QCoreApplication) in your main.cpp. If one if the latter is missing, QFileWatcher will still gladly accept whatever you tell it to do. When it fires signals, however, the callback to your slots will not take place.

        C++ and Python walk into a bar. C++ reuses the first glass.

        JonBJ R 2 Replies Last reply
        0
        • AxelViennaA AxelVienna

          You may have included the Q_OBJECT macro elsewhere in your code, I just don't see it here. You need it and you need to construct an instance of QApplication(int &, char **) (or QCoreApplication) in your main.cpp. If one if the latter is missing, QFileWatcher will still gladly accept whatever you tell it to do. When it fires signals, however, the callback to your slots will not take place.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @AxelVienna said in QFileSystemWatcher doesnt send signals to my slots:

          You may have included the Q_OBJECT macro elsewhere in your code, I just don't see it here.

          Untested, but unless you prove to me otherwise I don't think the OP has to have Q_OBJECT macro anywhere here, for the purposes of getting this to work. MyClass does not emit signals.

          AxelViennaA 1 Reply Last reply
          1
          • JonBJ JonB

            @AxelVienna said in QFileSystemWatcher doesnt send signals to my slots:

            You may have included the Q_OBJECT macro elsewhere in your code, I just don't see it here.

            Untested, but unless you prove to me otherwise I don't think the OP has to have Q_OBJECT macro anywhere here, for the purposes of getting this to work. MyClass does not emit signals.

            AxelViennaA Offline
            AxelViennaA Offline
            AxelVienna
            wrote on last edited by
            #5

            @JonB You are right, thanks for correcting!

            C++ and Python walk into a bar. C++ reuses the first glass.

            JonBJ 1 Reply Last reply
            0
            • AxelViennaA AxelVienna

              @JonB You are right, thanks for correcting!

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @AxelVienna
              It's not that it might not be a good idea, it was just that I didn't want the OP to think that would actually solve anything!

              It wouldn't do any harm for OP to verify the return results of the connect()s succeeded, to make sure, just I find that these days with the new style syntax it rarely fails, and they look OK to me.

              1 Reply Last reply
              0
              • AxelViennaA AxelVienna

                You may have included the Q_OBJECT macro elsewhere in your code, I just don't see it here. You need it and you need to construct an instance of QApplication(int &, char **) (or QCoreApplication) in your main.cpp. If one if the latter is missing, QFileWatcher will still gladly accept whatever you tell it to do. When it fires signals, however, the callback to your slots will not take place.

                R Offline
                R Offline
                RetroZelda
                wrote on last edited by RetroZelda
                #7

                @JonB said in QFileSystemWatcher doesnt send signals to my slots:

                @RetroZelda
                Don't know if this helps, but your code looks OK in principle. (Though you are asking for both directoryChanged and fileChanged on the same path, I'm not sure whether both of those can be emitted.) I presume path refers to a directory.

                QFileSystemWatcher will have problems/won't work if the path is on a network (e.g. NFS), or if it is a mount point. But I don't suppose you're using either of those. Try it on your home directory, or one directory down, and do specify a full path for path.

                I just attempted to connect a slot to only the "directoryChanged" signal with no luck.

                @AxelVienna said in QFileSystemWatcher doesnt send signals to my slots:

                You may have included the Q_OBJECT macro elsewhere in your code, I just don't see it here. You need it and you need to construct an instance of QApplication(int &, char **) (or QCoreApplication) in your main.cpp. If one if the latter is missing, QFileWatcher will still gladly accept whatever you tell it to do. When it fires signals, however, the callback to your slots will not take place.

                I dont have Q_OBJECT defined for this type. I think i'll eventually do this regardless based on what @JonB suggested

                @JonB said in QFileSystemWatcher doesnt send signals to my slots:

                @AxelVienna

                It wouldn't do any harm for OP to verify the return results of the connect()s succeeded, to make sure, just I find that these days with the new style syntax it rarely fails, and they look OK to me.

                I did edit my original post with the info about 10 minutes after posting it, so you might not have seen it. connect() does return "true" for everything

                However, I do have this getting printed in the output:

                "qt.qpa.xcb: QXcbConnection: XCB error: 5 (BadAtom), sequence: 462, resource id: 0, major code: 20 (GetProperty), minor code: 0".

                Im not exactly sure when this appeared, could this be related? It doesnt get printed immediately.

                Edit:
                I just attempted to run without any of these connections and that error does still get logged. I dont believe it would be related, so ill do some resaerch to get this addressed

                JonBJ 2 Replies Last reply
                0
                • R RetroZelda

                  @JonB said in QFileSystemWatcher doesnt send signals to my slots:

                  @RetroZelda
                  Don't know if this helps, but your code looks OK in principle. (Though you are asking for both directoryChanged and fileChanged on the same path, I'm not sure whether both of those can be emitted.) I presume path refers to a directory.

                  QFileSystemWatcher will have problems/won't work if the path is on a network (e.g. NFS), or if it is a mount point. But I don't suppose you're using either of those. Try it on your home directory, or one directory down, and do specify a full path for path.

                  I just attempted to connect a slot to only the "directoryChanged" signal with no luck.

                  @AxelVienna said in QFileSystemWatcher doesnt send signals to my slots:

                  You may have included the Q_OBJECT macro elsewhere in your code, I just don't see it here. You need it and you need to construct an instance of QApplication(int &, char **) (or QCoreApplication) in your main.cpp. If one if the latter is missing, QFileWatcher will still gladly accept whatever you tell it to do. When it fires signals, however, the callback to your slots will not take place.

                  I dont have Q_OBJECT defined for this type. I think i'll eventually do this regardless based on what @JonB suggested

                  @JonB said in QFileSystemWatcher doesnt send signals to my slots:

                  @AxelVienna

                  It wouldn't do any harm for OP to verify the return results of the connect()s succeeded, to make sure, just I find that these days with the new style syntax it rarely fails, and they look OK to me.

                  I did edit my original post with the info about 10 minutes after posting it, so you might not have seen it. connect() does return "true" for everything

                  However, I do have this getting printed in the output:

                  "qt.qpa.xcb: QXcbConnection: XCB error: 5 (BadAtom), sequence: 462, resource id: 0, major code: 20 (GetProperty), minor code: 0".

                  Im not exactly sure when this appeared, could this be related? It doesnt get printed immediately.

                  Edit:
                  I just attempted to run without any of these connections and that error does still get logged. I dont believe it would be related, so ill do some resaerch to get this addressed

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #8

                  @RetroZelda said in QFileSystemWatcher doesnt send signals to my slots:

                  "qt.qpa.xcb: QXcbConnection: ....

                  I believe this message has been reported elsewhere as a harmless one. It has nothing to do with your issue.

                  1 Reply Last reply
                  0
                  • R RetroZelda

                    @JonB said in QFileSystemWatcher doesnt send signals to my slots:

                    @RetroZelda
                    Don't know if this helps, but your code looks OK in principle. (Though you are asking for both directoryChanged and fileChanged on the same path, I'm not sure whether both of those can be emitted.) I presume path refers to a directory.

                    QFileSystemWatcher will have problems/won't work if the path is on a network (e.g. NFS), or if it is a mount point. But I don't suppose you're using either of those. Try it on your home directory, or one directory down, and do specify a full path for path.

                    I just attempted to connect a slot to only the "directoryChanged" signal with no luck.

                    @AxelVienna said in QFileSystemWatcher doesnt send signals to my slots:

                    You may have included the Q_OBJECT macro elsewhere in your code, I just don't see it here. You need it and you need to construct an instance of QApplication(int &, char **) (or QCoreApplication) in your main.cpp. If one if the latter is missing, QFileWatcher will still gladly accept whatever you tell it to do. When it fires signals, however, the callback to your slots will not take place.

                    I dont have Q_OBJECT defined for this type. I think i'll eventually do this regardless based on what @JonB suggested

                    @JonB said in QFileSystemWatcher doesnt send signals to my slots:

                    @AxelVienna

                    It wouldn't do any harm for OP to verify the return results of the connect()s succeeded, to make sure, just I find that these days with the new style syntax it rarely fails, and they look OK to me.

                    I did edit my original post with the info about 10 minutes after posting it, so you might not have seen it. connect() does return "true" for everything

                    However, I do have this getting printed in the output:

                    "qt.qpa.xcb: QXcbConnection: XCB error: 5 (BadAtom), sequence: 462, resource id: 0, major code: 20 (GetProperty), minor code: 0".

                    Im not exactly sure when this appeared, could this be related? It doesnt get printed immediately.

                    Edit:
                    I just attempted to run without any of these connections and that error does still get logged. I dont believe it would be related, so ill do some resaerch to get this addressed

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #9

                    @RetroZelda
                    Try the following standalone program (tested under Ubuntu 20.04) on your system:

                    #include <QApplication>
                    #include <QDir>
                    #include <QFileSystemWatcher>
                    #include <QTextEdit>
                    
                    int main(int argc, char *argv[])
                    {
                        QApplication a(argc, argv);
                        QTextEdit w;
                        w.show();
                        QFileSystemWatcher fsw;
                        fsw.addPath(QDir::homePath());
                        fsw.addPath(QDir::homePath() + "/testfile");  // create this before running
                        QObject::connect(&fsw, &QFileSystemWatcher::directoryChanged, [&w](const QString &path) { w.append(QString("directoryChanged : %1").arg(path)); });
                        QObject::connect(&fsw, &QFileSystemWatcher::fileChanged, [&w](const QString &path) { w.append(QString("fileChanged : %1").arg(path)); });
                        return a.exec();
                    }
                    

                    If you don't get any output as you play with files in your home directory you have some problem with QFileSystemWatcher not working on your system.

                    R 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @RetroZelda
                      Try the following standalone program (tested under Ubuntu 20.04) on your system:

                      #include <QApplication>
                      #include <QDir>
                      #include <QFileSystemWatcher>
                      #include <QTextEdit>
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication a(argc, argv);
                          QTextEdit w;
                          w.show();
                          QFileSystemWatcher fsw;
                          fsw.addPath(QDir::homePath());
                          fsw.addPath(QDir::homePath() + "/testfile");  // create this before running
                          QObject::connect(&fsw, &QFileSystemWatcher::directoryChanged, [&w](const QString &path) { w.append(QString("directoryChanged : %1").arg(path)); });
                          QObject::connect(&fsw, &QFileSystemWatcher::fileChanged, [&w](const QString &path) { w.append(QString("fileChanged : %1").arg(path)); });
                          return a.exec();
                      }
                      

                      If you don't get any output as you play with files in your home directory you have some problem with QFileSystemWatcher not working on your system.

                      R Offline
                      R Offline
                      RetroZelda
                      wrote on last edited by RetroZelda
                      #10

                      @JonB

                      @JonB said in QFileSystemWatcher doesnt send signals to my slots:

                      @RetroZelda
                      Try the following standalone program (tested under Ubuntu 20.04) on your system:

                      #include <QApplication>
                      #include <QDir>
                      #include <QFileSystemWatcher>
                      #include <QTextEdit>
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication a(argc, argv);
                          QTextEdit w;
                          w.show();
                          QFileSystemWatcher fsw;
                          fsw.addPath(QDir::homePath());
                          fsw.addPath(QDir::homePath() + "/testfile");  // create this before running
                          QObject::connect(&fsw, &QFileSystemWatcher::directoryChanged, [&w](const QString &path) { w.append(QString("directoryChanged : %1").arg(path)); });
                          QObject::connect(&fsw, &QFileSystemWatcher::fileChanged, [&w](const QString &path) { w.append(QString("fileChanged : %1").arg(path)); });
                          return a.exec();
                      }
                      

                      If you don't get any output as you play with files in your home directory you have some problem with QFileSystemWatcher not working on your system.

                      I just tested this and I do not get any prints when adding, renaming, editing, or removing a file in my home directory.

                      I made this test script to ensure I could watch any directory, and this does work for me. I even tested it from calling it within "main" in the test program to see if there was a permissions issue, but it worked in there as well.

                      #!/bin/bash
                      inotifywait -m ~ -e create -e moved_to |
                      while read dir action file; do
                          echo "$file - $action - $dir"
                      done
                      

                      is there a method towards enabling more "verbose logging", or would any kind of issue(like an assert or internal error) already be logged if one occurred?

                      edit:
                      also, this is my QT version

                      $ qmake --version
                      QMake version 3.1
                      Using Qt version 5.15.2 in /usr/lib/x86_64-linux-gnu
                      
                      JonBJ 1 Reply Last reply
                      0
                      • R RetroZelda

                        @JonB

                        @JonB said in QFileSystemWatcher doesnt send signals to my slots:

                        @RetroZelda
                        Try the following standalone program (tested under Ubuntu 20.04) on your system:

                        #include <QApplication>
                        #include <QDir>
                        #include <QFileSystemWatcher>
                        #include <QTextEdit>
                        
                        int main(int argc, char *argv[])
                        {
                            QApplication a(argc, argv);
                            QTextEdit w;
                            w.show();
                            QFileSystemWatcher fsw;
                            fsw.addPath(QDir::homePath());
                            fsw.addPath(QDir::homePath() + "/testfile");  // create this before running
                            QObject::connect(&fsw, &QFileSystemWatcher::directoryChanged, [&w](const QString &path) { w.append(QString("directoryChanged : %1").arg(path)); });
                            QObject::connect(&fsw, &QFileSystemWatcher::fileChanged, [&w](const QString &path) { w.append(QString("fileChanged : %1").arg(path)); });
                            return a.exec();
                        }
                        

                        If you don't get any output as you play with files in your home directory you have some problem with QFileSystemWatcher not working on your system.

                        I just tested this and I do not get any prints when adding, renaming, editing, or removing a file in my home directory.

                        I made this test script to ensure I could watch any directory, and this does work for me. I even tested it from calling it within "main" in the test program to see if there was a permissions issue, but it worked in there as well.

                        #!/bin/bash
                        inotifywait -m ~ -e create -e moved_to |
                        while read dir action file; do
                            echo "$file - $action - $dir"
                        done
                        

                        is there a method towards enabling more "verbose logging", or would any kind of issue(like an assert or internal error) already be logged if one occurred?

                        edit:
                        also, this is my QT version

                        $ qmake --version
                        QMake version 3.1
                        Using Qt version 5.15.2 in /usr/lib/x86_64-linux-gnu
                        
                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by
                        #11

                        @RetroZelda
                        The code is correct, and should work. I note that your command line inotifywait does work.

                        I do not know why Qt's QFileSystemWatcher is not working for you under Debian. I can only suggest you look at the source code at https://code.woboq.org/qt5/qtbase/src/corelib/io/qfilesystemwatcher.cpp.html and https://code.woboq.org/linux/linux/fs/notify/inotify/inotify.h.html to see if you can figure what the issue is in your platform.

                        It may not be "nice", but you have the option of copying/amending some of this code to make the necessary direct OS call in your own code if necessary.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved