QFileSystemWatcher不会在控制台应用程序中发出fileChanged()

问题描述:

在我的文件中console.h/.cpp我有一个小类,它只是要求用户键入一些文本,然后再打印文本,直到用户输入“退出”(参见方法consoleMain())。但是,在main.cpp我也有一个 QFileSystemWatcher它观看文件MyTextFile.txt并且每当文本文件更改时调用Console::slotFileChanged(QString)。不幸的是,QFileSystemWatcher不起作用。当我更改文本文件时,从未执行Console::slotFileChanged(QString)。据我所知,QFileSystemWatcher只适用于主事件循环已经开始,这也是我的代码中的情况。 当我在main.cpp中禁用QTimer::singlaShotemit 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(); 
} 
+0

显式调用'consoleMain'。直到它完成运行,它运行。据我所知,Qt几乎没有控制台支持。解决它的最简单方法可能是在控制台上放置一个线程,并在主线事件循环中运行不同线程,并让控制台发送消息与主事件循环进行通信?谷歌发现http://*.com/a/18889631/1774667答案似乎通过邮件传递键入的字符,你必须重新手动。 – Yakk

好吧,也就迎刃而解了。我已经尝试过使用不同线程的Yakk的想法(感谢Yakk的想法)。我不得不介绍一个名为MyObject的新子类QObject。在其构造函数中,我为控制台对象创建了Console和一个新的QThreadQFileSystemWatcher创建于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)