├── README.md ├── qml.qrc ├── main.qml ├── LiveCoding.pro ├── filewatcher.h ├── main.cpp ├── .gitignore └── filewatcher.cpp /README.md: -------------------------------------------------------------------------------- 1 | # LiveCoding 2 | Minimal example on how to setup a QFileSystemWatcher to enable live coding in QML 3 | -------------------------------------------------------------------------------- /qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | main.qml 4 | 5 | 6 | -------------------------------------------------------------------------------- /main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.5 2 | 3 | Rectangle { 4 | anchors.fill: parent 5 | 6 | Text { 7 | anchors.centerIn: parent 8 | text: "hello world" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /LiveCoding.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | 3 | QT += qml quick 4 | CONFIG += c++11 5 | 6 | SOURCES += main.cpp \ 7 | filewatcher.cpp 8 | 9 | RESOURCES += qml.qrc 10 | 11 | # Additional import path used to resolve QML modules in Qt Creator's code model 12 | QML_IMPORT_PATH = 13 | 14 | # Default rules for deployment. 15 | qnx: target.path = /tmp/$${TARGET}/bin 16 | else: unix:!android: target.path = /opt/$${TARGET}/bin 17 | !isEmpty(target.path): INSTALLS += target 18 | 19 | HEADERS += \ 20 | filewatcher.h 21 | -------------------------------------------------------------------------------- /filewatcher.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEWATCHER_H 2 | #define FILEWATCHER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class QString; 11 | 12 | class FileWatcher : public QObject 13 | { 14 | Q_OBJECT 15 | public: 16 | FileWatcher(std::function callback); 17 | 18 | void setDirectory(const QString &path); 19 | 20 | public slots: 21 | void directoryChanged(const QString &path); 22 | void fileChanged(const QString &path); 23 | 24 | private: 25 | void addPaths(); 26 | 27 | private: 28 | std::function mCallback; 29 | QFileSystemWatcher mWatcher; 30 | QDir mDir; 31 | QTimer mTimer; 32 | }; 33 | 34 | #endif // FILEWATCHER_H 35 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "filewatcher.h" 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | QGuiApplication app(argc, argv); 11 | 12 | QQuickView view; 13 | 14 | const QDir DIRECTORY("D:/Dev/qt projects/LiveCoding"); 15 | const QUrl SOURCE_URL = QUrl::fromLocalFile(DIRECTORY.filePath("main.qml")); 16 | 17 | view.setSource(SOURCE_URL); 18 | view.setWidth(600); 19 | view.setHeight(400); 20 | view.show(); 21 | 22 | FileWatcher watcher([&view, SOURCE_URL](){ 23 | view.engine()->clearComponentCache(); 24 | view.setSource(SOURCE_URL); 25 | }); 26 | 27 | watcher.setDirectory(DIRECTORY.absolutePath()); 28 | 29 | return app.exec(); 30 | } 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | 41 | # xemacs temporary files 42 | *.flc 43 | 44 | # Vim temporary files 45 | .*.swp 46 | 47 | # Visual Studio generated files 48 | *.ib_pdb_index 49 | *.idb 50 | *.ilk 51 | *.pdb 52 | *.sln 53 | *.suo 54 | *.vcproj 55 | *vcproj.*.*.user 56 | *.ncb 57 | *.sdf 58 | *.opensdf 59 | *.vcxproj 60 | *vcxproj.* 61 | 62 | # MinGW generated files 63 | *.Debug 64 | *.Release 65 | 66 | # Python byte code 67 | *.pyc 68 | 69 | # Binaries 70 | # -------- 71 | *.dll 72 | *.exe 73 | 74 | -------------------------------------------------------------------------------- /filewatcher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "filewatcher.h" 5 | 6 | /** 7 | * @brief FileWatcher::FileWatcher 8 | * This class can monitor file changes in a directory and calls a callback 9 | * in response 10 | * @param callback 11 | * The callback function to be executed whenever changes are detected 12 | */ 13 | FileWatcher::FileWatcher(std::function callback) 14 | : mCallback(callback) 15 | { 16 | QObject::connect(&mWatcher, &QFileSystemWatcher::directoryChanged, this, &FileWatcher::directoryChanged); 17 | QObject::connect(&mWatcher, &QFileSystemWatcher::fileChanged, this, &FileWatcher::fileChanged); 18 | 19 | // configure the timer to signal the changes to the callback 20 | mTimer.setInterval(100); 21 | mTimer.setSingleShot(true); 22 | 23 | // configure directory filters 24 | mDir.setFilter(QDir::Files | QDir::NoSymLinks); 25 | mDir.setNameFilters(QStringList() << "*.qml"); 26 | 27 | // connect timer to callback function 28 | QObject::connect(&mTimer, &QTimer::timeout, mCallback); 29 | } 30 | 31 | /** 32 | * @brief FileWatcher::addPaths 33 | * Adds the paths of the files to be monitored in the current directory 34 | */ 35 | void FileWatcher::addPaths() 36 | { 37 | QStringList entries = mDir.entryList(); 38 | for (int i=0; i