我提前道歉,我对QT非常陌生(对c++也相当陌生)
我正在尝试设置一个程序,该程序将在任何特定文件更改时执行函数。尽管在谷歌上花了几个小时阅读QT上提供的文档,但我找不到一种方法来让myfunction()在SSOpen_Log被编辑时执行
目前我的代码看起来像这样(SOpen_Log是一个QString声明在.h):
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QFileSystemWatcher watcher;
watcher.addPath(SOpen_Log);
MainWindow::connect(&watcher, SIGNAL(fileChanged(QString)), this, SLOT(myfunction()));
}
MainWindow::myfunction()
{
//mycode executes here
}
您在堆栈上分配了实例,因此在构造函数结束时它将被销毁。我建议您为实例创建一个类成员,以便它在整个类中保持有效。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_watcher.addPath(SOpen_Log);
MainWindow::connect(&m_watcher, SIGNAL(fileChanged(QString)), this, SLOT(myfunction()));
}
没有必要把它放在堆上,有效地使用指针,尽管这也是一个可以考虑的选项。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QFileSystemWatcher *watcher = new QFileSystemWatcher(this);
watcher->addPath(SOpen_Log);
MainWindow::connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(myfunction()));
}
虽然我们在这里,我还想提到使用新的信号槽语法风格,而不是旧的。在运行时检查旧和新一是在编译时检查。因此,您可以在编译期间捕获它的任何问题,而不是在运行时。
一个完整而简单的例子:Dirwatcher.h
class DirWatcher : public QObject
{
Q_OBJECT
public:
static const int sMaxCount = 5;
explicit DirWatcher(const QString& root, QObject* parent = nullptr);
virtual ~DirWatcher();
private slots:
void hDirChanged(const QString&);
void hFileChanged(const QString&);
private:
quint64 m_rbSize;
QByteArray m_ringBuffer[10];
QFileSystemWatcher m_watcher;
QDir m_root;
QSet<QString> m_directories;
QMap<QString, QSet<QString>> m_abspaths;
QString m_lastKey;
};
和Dirwatcher.cpp
namespace
{
void split(const char* str, const char* delim, std::vector<std::string>& out)
{
const char* begin = str;
const char* it = strstr(str, delim);
if (it != NULL)
{
std::string data{begin, it};
out.push_back(data);
it++;
split(it, delim, out);
} else {
std::string data{str};
out.push_back(data);
}
}
}
DirWatcher::DirWatcher(const QString &root, QObject* parent):
QObject(parent), m_root(root), m_rbSize{10}
{
m_watcher.addPath(root);
QObject::connect(&m_watcher, SIGNAL(directoryChanged(const QString&)),
this, SLOT(hDirChanged(const QString&)));
QObject::connect(&m_watcher, SIGNAL(fileChanged(const QString&)),
this, SLOT(hFileChanged(const QString&)));
}
DirWatcher::~DirWatcher()
{
}
void DirWatcher::hDirChanged(const QString &path)
{
QDirIterator it(m_root.path());
while (it.hasNext()) {
QString d = it.next();
if (d.at(0) == '.' || d.at(d.size()-1) == '.') {
} else {
if (!m_directories.contains(d)){
m_directories << d;
m_lastKey = d;
}
}
}
#if 0 //delete directories when count reaches...
if (m_directories.count() > DirWatcher::sMaxCount) {
QSetIterator<QString> setit(m_directories);
while (setit.hasNext()) {
QString toDel = setit.next();
if (toDel != m_lastKey) {
QDir rem (toDel);
rem.removeRecursively();
}
}
m_directories.clear();
m_directories << m_lastKey;
}
#endif
std::cout << "##############################################rn";
QSetIterator<QString> setit(m_directories);
while (setit.hasNext()) {
QString d = setit.next();
if (d.contains(".tlf")) {
m_watcher.addPath(d);
}
std::cout << d.toStdString() << std::endl;
}
}
void DirWatcher::hFileChanged(const QString& file)
{
static size_t cnt = 0;
QFile f{file};
if (f.open(QFile::ReadOnly)) {
quint64 s = f.size();
f.seek(f.size()-f.size()/2);
while (!f.atEnd()) {
QByteArray data = f.readLine();
m_ringBuffer[cnt++ % m_rbSize]=data;
}
}
std::cout << "----------------- B E G I N ----------------------rn";
for(auto i : m_ringBuffer) {
std::cout << "~~~~~~rn";
std::cout << i.toStdString().c_str() << "rn";
}
}
这是一个真正的后台监控作业过程,用于在给定的时间或计数上删除文件,但是如果您调试它,您将了解代码中缺少什么。