simple Notepad
-
I have followed a simple notepad tutorial and all seems good.
Couple of questions. When I write in the notepad save the text file then change text - how do I get the app to recognise changes have been made, so that when I go to close the app it knows a change has happened and asks to save before close? Trivial I know but wonder if it can be done?Thanks James
-
@jamesmfarrow
So it is your job to maintain a boolean flag, often called a "dirty" flag, to indicate whether the document has been changed since the last time it was saved. An unsaved changed file is referred to as being "dirty".You will want to connect a slot to whatever widget you are using --- say a
QTextEdit
--- on itstextChanged
signal, and the slot should set the dirty flag totrue
. When the user wants to quit you look at this flag and warn if it is set. Whenever the user saves the file you set the flag tofalse
. So immediately after saving, and before any further editing, the user can exit without warning.Makes sense?
-
Thanks! I have found on_textEdit_textChanged();
I now need to work out how to fit bit in like you said!Thanks again.
-
@jamesmfarrow
Hint: it's just a member variable of something to do with your document, or even of your main window if that's all you've got.Further, if I'm not confusing you. If you are using a
QTextEdit
that has an associated underlying QTextDocument * document(). And that already has a pre-provided flag for this for you, Using QTextEdit as an EditorQTextDocument
provides anisModified()
function which will return true if the text has been modified since it was either loaded or since the last call tosetModified
with false as argument.So you could use that as your "dirty" flag. Clear that flag whenever you save. In this case, you won't even need to slot onto
textChanged()
, asQTextEdit
will be setting theQTextDocument::setModified(true)
for you behind the scenes when the user changes content. But I think it's as well to understand the explicit principle if you needed to implement for yourself. -
looks like I am using Qtextedit - see what I can do!! -
@jamesmfarrow
That's a pretty big screenshot!Read my post just above which I made just before your latest post, explaining how you can achieve it without having to maintain the flag for yourself if you don't want to.
-
if(currentFile.isModified()) { std::cout << "modified" << std::endl; save();}
else if(currentFile.isEmpty()) { std::cout << "empty" << std::endl; QApplication::quit(); }
else QApplication::quit();When close is triggered, if file has changed - save it.
if file is empty i.e. nothing has been typed simply quit.Problem is isEmpty is true even when I have typed - it must only change when file saved??
-
@jamesmfarrow
I don't know what's going on with yourisEmpty()
, might depend where this code of yours is situated. I presume yourcurrentFile
is yourtextEdit->document()
, and is correct? Don't call itcurrentFile
, bettercurrentDocument
, or just usetextEdit->document()
whenever you want to access it, as that can change.You don't need to check
isEmpty()
here anyway. Either the file is modified and needs saving or it is not and does not, I think. Having said that, you may nonetheless wish to investigate what is going on withisEmpty()
if you say the document is not empty.isEmpty()
should reflect the state of the document, nothing to do with whether you have saved or not. -
Here is the code, I made some big 'cock ups' and had to pull from git. Back to start :(
As you can see currentFile is a QString not QDocument... ?QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{
Q_OBJECT //base class handles events etcpublic:
MainWindow(QWidget *parent = nullptr); //by passing in nullptr we are stating that it has no parents
~MainWindow(); //destructor
bool not_saved{true};void save();
private slots:
void on_actionNew_triggered();void on_actionOPen_triggered(); void on_actionSave_as_triggered(); void on_actionPrint_triggered(); void on_actionExit_triggered(); void on_actionCut_triggered(); void on_actionCopy_triggered(); void on_actionPaste_triggered(); void on_actionUndo_triggered(); void on_actionRedo_triggered(); bool on_textEdit_textChanged();
private:
Ui::MainWindow *ui;
QString currentFile;};
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//set text edit widget (central) to take up all screen space
this->setCentralWidget(ui->textEdit);
}MainWindow::~MainWindow()
{
delete ui;
}void MainWindow::on_actionNew_triggered()
{
currentFile.clear();//clears file
ui->textEdit->setText(QString()); //clear text edit widget
}void MainWindow::on_actionOPen_triggered()
{
QString filename = QFileDialog::getOpenFileName((this), "Open the file");
QFile file(filename); //object for reading/writing files
currentFile = filename;
if(!file.open(QIODevice::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, "Warning", "Can not open file " + file.errorString());
return;
}
setWindowTitle(filename);
QTextStream in(&file);
QString text = in.readAll();
ui->textEdit->setText(text);
file.close();
}void MainWindow::on_actionSave_as_triggered()
{
QString filename = QFileDialog::getSaveFileName(this, "Save as");
QFile file(filename); //object for reading/writing files
if(!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, "Warning", "Can not save file " + file.errorString());
return;
}
currentFile = filename;
setWindowTitle(filename);
QTextStream out(&file);
QString text = ui->textEdit->toPlainText();
out << text;
file.close();
}void MainWindow::on_actionPrint_triggered()
{
QPrinter printer;
printer.setPaperName("Photosmart 5520");
QPrintDialog pDialog(&printer, this);
if(pDialog.exec() == QDialog::Rejected) {
QMessageBox::warning(this, "Warning", "Can not access printer");
return;
}
ui->textEdit->print(&printer);
}void MainWindow::save() {
QMessageBox::StandardButton reply; reply = QMessageBox::question(this, "Test", "File not saved\n\nSave file ?", QMessageBox::Yes|QMessageBox::No); if (reply == QMessageBox::Yes) { on_actionSave_as_triggered(); QApplication::quit(); } else { QApplication::quit(); }
}
void MainWindow::on_actionExit_triggered()
{
if(on_textEdit_textChanged()) save();
else QApplication::quit();
}void MainWindow::on_actionCopy_triggered()
{
ui->textEdit->copy();
}void MainWindow::on_actionPaste_triggered()
{
ui->textEdit->paste();
}void MainWindow::on_actionCut_triggered()
{
ui->textEdit->cut();
}void MainWindow::on_actionUndo_triggered()
{
ui->textEdit->undo();
}void MainWindow::on_actionRedo_triggered()
{
ui->textEdit->redo();
}bool MainWindow::on_textEdit_textChanged()
{
return true;
} -
@jamesmfarrow said in simple Notepad:
When you paste code in this forum, please use the Code toolbutton to put lines of just triple-backticks above & below your pasted code. See how much more readable that makes it for us? :)As you can see currentFile is a QString not QDocument... ?
currentFile
is the name of the file you choose to save. CallingisModified()
orisEmpty()
on that is nonsense --- and of courseQString::isEmpty()
always returns false on that for a non-empty filename. Sort out your usage of the current filename you wish to use, which has nothing to do with thedocument()
yourQTextEdit
is editing.You are supposed to have read the references I gave you and understood that you are to call
isModified()
/isEmpty()
onui->textEdit->document()
. Or, go back to my original maintain your own flag if you don't want to use that.void MainWindow::on_actionExit_triggered() { if(on_textEdit_textChanged()) save(); else QApplication::quit(); }
Calling
on_textEdit_textChanged()
here is nonsense. (Not to mention that youron_textEdit_textChanged()
always just goesreturn true;
.) That is supposed to be a slot which gets called by the Qt infrastructure when you change the text (e.g. type a character into theQTextEdit
), viaQTextEdit::textChanged
signal. Your check for save on exit is supposed to be, say,if (ui->textEdit->document()->isModified()) save();
At this point you have conceptual reading up to do. It's general programming, and I must leave you to find out your own stuff.
-
@JonB said in simple Notepad:
Using QTextEdit as an Editor
Thanks for your help - I appreciate it!! I started with C++ about 6 months ago and have been 'trying' to learn as much as I can when I can. This is my first attempt with Qt. Its good to have someone point out the mistakes etc.
Apologies for not using codehooks.A big learning curve...! Rest assured I will go and try to implement your advice and knowledge - no doubt " I'll be back "
Thanks again!
-
Thanks to JonB I have now managed to get things working as I want.