update text edit at run time.
-
Hi,
I have created a Qt Widget application. I am using a text edit to update the text read from a txt file. I want to update the text edit at run time as and when user enters the text in the txt file. or as an log file is getting created, I want to read the text from the log file and update the text edit at the same time.
Any help would be appreciated.
Thanks.
-
@mbatra
Well, it should do, that's what it's there for. You can find other people using it on the web. You can post minimal code if you want us to check you are doing the right thing.It can only notify when changes are actually written to the file, e.g. not if they are still buffered in memory by the changing application.
-
@JonB
This is the code that I have written:void MainWindow::slotFileChanged(QString text)
{
qDebug()<<text<<endl;
}void MainWindow::onstartButtonClicked()
{
QFileSystemWatcher watcher(this);
watcher.addPath("D:\MB\Selection\Resources\log.log");connect(&watcher, SIGNAL(fileChanged(QString)), this, SLOT(slotFileChanged(QString)));
}
-
Your code doesn't work because the instance of QFileSystemWatcher is destroyed when onStartButtonClicked is terminated. So basically the watcher is created and immediately destroyed, so you'll never get any signal emitted from it. You must keep an instance of QFileSystemWatcher as a member of your MainWindow class.
-
Hi,
Thanks for your response. Now, I have added the below code:
.h file:
QFileSystemWatcher *watcher;
public slots:
void slotFileChanged(QString &text);.cpp file:
void MainWindow::slotFileChanged(QString &text)
{
qDebug()<<"slotFileChanged Called\n";
qDebug()<<text<<endl;
}void MainWindow::onstartButtonClicked()
{
watcher = new QFileSystemWatcher(this);
watcher->addPath(":/log.log");connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(slotFileChanged(QString)));
}
is it correct now.
Still I am not getting the messages displayed in the slotchanged function.
-
Hi,
I have added this now, it returns false;
bool b = watcher->addPath("D:\Putty_Log\log.log");
Can we specify the full path like this. Does it accepts.
It also gives this error message:
QObject::connect: No such signal QFileSystemWatcher::fileChanged(QString &)
QObject::connect: (receiver name: 'MainWindow')Thanks.
-
@mbatra said in update text edit at run time.:
bool b = watcher->addPath("D:\Putty_Log\log.log");
@mbatra When using backslash in string you must escape using double
\\
, which gives youD:\\Putty_Log\\log.log
as a path.@mbatra said in update text edit at run time.:
void MainWindow::onstartButtonClicked()
{
watcher = new QFileSystemWatcher(this);
watcher->addPath(":/log.log");
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(slotFileChanged(QString)));}
You don't need necessarily to use a pointer for your QFileSystemWatcher member object. As you have done here this will create a new instance every time
onstartButtonClicked
is called, which is probaly not what you want. But it will probably work anyway. -
@mbatra said in update text edit at run time.:
watcher->addPath(":/log.log");
This is a Qt resource path. It won't be accepted for watching, and in any case Qt resource files are read-only so it will never change.
bool b = watcher->addPath("D:\Putty_Log\log.log");
Single backslash characters must be doubled in a C++ literal string.
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(slotFileChanged(QString)));
QObject::connect: No such signal QFileSystemWatcher::fileChanged(QString &)
It is much easier if you use the "new"-style
connect()
syntax, which was introduced over a decade ago.The signature is
QFileSystemWatcher::fileChanged(const QString &)
, I don't know thatSLOT()
let's you get away without thatconst
.As @Gojir4 says, you should not create a new
QFileSystemWatcher
object each time a button is pressed. -
Hi Jon,
Thanks for your response. Now the code is working fine. I have created the QFileSystemWatcher object in the constructor only once...not in the button everytime.
Thanks for correcting me.
Now the file is getting checked and when its updated the text edit contents are also updated, but only when I click on the button, the contents are getting updated in the text edit.
I want the text edit contents should get updated automatically (dynamically) as and when the contents in the txt file is getting changed.Please see the code below:
void MainWindow::onstartButtonClicked()
{
textEdit->show();bool b = watcher->addPath("D:/Putty_Log/Putty.log"); qDebug()<<"\nAddPath Return Value = "<<b; emit slotFileChanged("D:/Putty_Log/Putty.log");
}
void MainWindow::slotFileChanged(QString text)
{
qDebug()<<"slotFileChanged Called\n";
qDebug()<<text<<endl;QFile inputFile(text); inputFile.open(QIODevice::ReadOnly); if (!inputFile.isOpen()) return; QTextStream stream(&inputFile); for (QString line = stream.readLine(); !line.isNull(); line = stream.readLine()) { textEdit->append(line); };
}
Any help would be appreciated.
-
@mbatra said in update text edit at run time.:
emit slotFileChanged("D:/Putty_Log/Putty.log");
And where did you connect the signal from the file watcher to your slot? How is it supposed to work when you don't connect the slot?
-
@mbatra said in update text edit at run time.:
emit slotFileChanged("
Why emit?
Simply call slotFileChanged as normal method.
If it does not work: did you do any debugging? Is slotFileChanged called? What happens inside slotFileChanged (can the file be successfully opened?). -
@mbatra There is NO need for emit at all!
I just realised that your code makes no sense:void MainWindow::onstartButtonClicked() { textEdit->show(); bool b = watcher->addPath("D:/Putty_Log/Putty.log"); qDebug()<<"\nAddPath Return Value = "<<b; emit slotFileChanged("D:/Putty_Log/Putty.log"); }
You need to call slotFileChanged in the slot connected to the signal from the watcher. Currently you call it in onstartButtonClicked - so why should it be called everytime the file is edited? Think about the logic.
-
@mbatra said in update text edit at run time.:
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(slotFileChanged(QString)));
This ought be all you need. When the watcher sees a file change it emits the
fileChanged()
signal and yourslotFileChanged()
slot should be called.