QFileSystemWatcher不会在控制台应用程序中发出fileChanged()
在我的文件中console.h/.cpp我有一个小类,它只是要求用户键入一些文本,然后再打印文本,直到用户输入“退出”(参见方法consoleMain()
)。但是,在main.cpp我也有一个 QFileSystemWatcher
它观看文件MyTextFile.txt并且每当文本文件更改时调用Console::slotFileChanged(QString)
。不幸的是,QFileSystemWatcher
不起作用。当我更改文本文件时,从未执行Console::slotFileChanged(QString)
。据我所知,QFileSystemWatcher
只适用于主事件循环已经开始,这也是我的代码中的情况。 当我在main.cpp中禁用QTimer::singlaShot
和emit console.signalStart()
主事件循环替换它不会进入,但我看到的消息QFileSystemWatcher
(“文件改变了!”)后,我进入“跳槽”。 问题是:是否可以让用户与控制台进行交互,并在文本文件并行更改时让FileWatcher发出信号? (我也尝试把QFileSystemWatcher
到控制台类堆上创建它,遗憾的是它并没有改变任何东西)QFileSystemWatcher不会在控制台应用程序中发出fileChanged()
这里是我的代码:
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();
}
好吧,也就迎刃而解了。我已经尝试过使用不同线程的Yakk的想法(感谢Yakk的想法)。我不得不介绍一个名为MyObject
的新子类QObject
。在其构造函数中,我为控制台对象创建了Console
和一个新的QThread
。 QFileSystemWatcher
创建于main.cpp以及MyObjcet
的实例。请参见下面的代码:
myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include "console.h"
#include <QThread>
#include <QCoreApplication>
class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(QObject *parent = 0);
~MyObject();
private:
QThread *thread;
Console *console;
signals:
void signalStart();
public slots:
void slotFileChanged(QString text);
void slotEnd();
};
#endif // MYOBJECT_H
myobject.cpp
#include "myobject.h"
MyObject::MyObject(QObject *parent): QObject(parent)
{
console = new Console;
thread = new QThread(this);
console->moveToThread(thread);
thread->start();
connect(this, SIGNAL(signalStart()), console, SLOT(consoleMain()));
connect(console, SIGNAL(signalEnd()), this, SLOT(slotEnd()));
emit signalStart();
}
MyObject::~MyObject()
{
thread->quit();
thread->wait();
}
void MyObject::slotFileChanged(QString text)
{
console->displayChangedFileText(text);
}
void MyObject::slotEnd()
{
QCoreApplication::exit(0);
}
的main.cpp
#include "myobject.h"
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFileSystemWatcher *watcher = new QFileSystemWatcher(&a);
watcher->addPath("C:/MyTextFile.txt");
MyObject *object = new MyObject(&a);
QObject::connect(watcher, SIGNAL(fileChanged(QString)), object, SLOT(slotFileChanged(QString)));
std::cout << "Enter main event loop now" << std::endl;
return a.exec();
}
console.h/.cpp是未知的,只有Console::slotFileChanged(QString)
被替换为Console::displayChangedFileText(QString)
。
显式调用'consoleMain'。直到它完成运行,它运行。据我所知,Qt几乎没有控制台支持。解决它的最简单方法可能是在控制台上放置一个线程,并在主线事件循环中运行不同线程,并让控制台发送消息与主事件循环进行通信?谷歌发现http://*.com/a/18889631/1774667答案似乎通过邮件传递键入的字符,你必须重新手动。 – Yakk