in my files console.h/.cpp i have a small class which just asks the user to type in some text and then just prints the text again until the user enters "quit" (see method consoleMain()). However, in main.cpp I also have a
QFileSystemWatcher which watches the file MyTextFile.txt and calls Console::slotFileChanged(QString) whenever the text file changes. Unfortunately the QFileSystemWatcher does not work. Console::slotFileChanged(QString) is never executed when I change the text file. As far as I know, QFileSystemWatcher works only if the main event loop has been started and this is also the case in my code.
When I disable the QTimer::singlaShot in the main.cpp and replace it by emit console.signalStart()
the main event loop will not be entered, but I see the message of the QFileSystemWatcher ("File changed!") after I enter "quit".
The question is: Is it possible to let the user interact with the console and let the FileWatcher emit the signal when the text file is changed in parallel?
(I've also tried to put the QFileSystemWatcher into the console class and creating it on the heap; unfortunately it didn't change anything)
Here is my code:
console.h
#ifndef CONSOLE_H
#define CONSOLE_H
#include <iostream>
#include <QObject>
#include <QFileSystemWatcher>
class Console: public QObject
{
Q_OBJECT
public:
Console(QObject *parent = 0);
~Console();
signals:
void signalStart();
void signalEnd();
public slots:
void consoleMain();
void slotFileChanged(QString text);
void slotEmit();
};
#endif // CONSOLE_H
console.cpp
#include "console.h"
Console::Console(QObject *parent): QObject(parent)
{
}
Console::~Console()
{
}
void Console::consoleMain()
{
bool isRunning = true;
std::string in;
while (isRunning)
{
std::cout << ">" << std::flush;
std::getline(std::cin, in);
if (in.compare("quit") == 0)
isRunning = false;
else
std::cout << "You have entered: " << in << std::endl;
}
emit signalEnd();
}
void Console::slotFileChanged(QString text)
{
Q_UNUSED(text);
std::cout << "File changed!" << std::endl;
}
void Console::slotEmit()
{
emit signalStart();
}
main.cpp
#include "console.h"
#include <QCoreApplication>
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFileSystemWatcher watcher(&a);
watcher.addPath("C:/MyTextFile.txt");
Console console(&a);
QObject::connect(&console, SIGNAL(signalStart()), &console, SLOT(consoleMain()));
QObject::connect(&console, SIGNAL(signalEnd()), &a, SLOT(quit()));
QObject::connect(&watcher, SIGNAL(fileChanged(QString)), &console, SLOT(slotFileChanged(QString)));
QTimer::singleShot(0, &console, SLOT(slotEmit()));
//emit console.signalStart();
std::cout << "Enter main event loop now" << std::endl;
return a.exec();
}
Ok, it is solved. I've tried Yakk's idea using different threads (thanks for the idea Yakk). I had to introduce a new subclass of
QObjectcalledMyObject. In its constructor I create theConsoleand a newQThreadfor the console object. TheQFileSystemWatcheris created in main.cpp as well as an instance ofMyObjcet. See code below:myobject.h
myobject.cpp
main.cpp
console.h/.cpp are unchnaged, only
Console::slotFileChanged(QString)was replaced byConsole::displayChangedFileText(QString).