2015-04-22 23 views
1

在我的文件中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://stackoverflow.com/a/18889631/1774667答案似乎通過郵件傳遞鍵入的字符,你必須重新手動。 – Yakk

回答

0

好吧,也就迎刃而解了。我已經嘗試過使用不同線程的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)

相關問題