What code to use in an app to make it not load the same file twice



  • Hi all,

    Here is the program from the book "C++-GUI-Programming-with-Qt-4-2nd Edition". If possible please take a look at pages 83 through 85.

    I want to make two changes:
    1- Using a code make the program not open the same file twice.
    2- When I click the "exit" button of the File menu, make all opened files closed.

    This is of exit in: void MainWindow::createActions():

    closeAction = new QAction(tr("&Close"), this);
        closeAction->setShortcut(QKeySequence::Close);
        closeAction->setStatusTip(tr("Close this window"));
        connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));
    
        exitAction = new QAction(tr("E&xit"), this);
        exitAction->setShortcut(tr("Ctrl+Q"));
        exitAction->setStatusTip(tr("Exit the application"));
        connect(exitAction, SIGNAL(triggered()),
                qApp, SLOT(closeAllWindows()));
    

    My main.cpp:

    #include <QApplication>
    #include <QSplashScreen>
    #include "mainwindow.h"
    
    int main(int argc, char* argv[])
    {
       QApplication app(argc, argv);
    
       QSplashScreen* splash = new QSplashScreen;
       splash->setPixmap(QPixmap(":/images/splash.jpg"));
       splash->show();
    
       Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop;
       splash->showMessage(QObject::tr("Setting up the main window..."),
       topRight, Qt::white);
    
        MainWindow* mainWin = new MainWindow;
    
        if(argc > 1)
            mainWin->loadFile(argv[1]);
    
        mainWin->show();
        splash->finish(mainWin);
        delete splash;
    
        return app.exec();
    }
    

    Here is also the constructor of MainWindow. I've used recentFiles as static.

    QStringList MainWindow::recentFiles;
    MainWindow::MainWindow()
    {
        spreadsheet = new Spreadsheet;
        setCentralWidget(spreadsheet);
    
        createActions();
        createMenus();
        createContextMenu();
        createToolBars();
        createStatusBar();
    
        readSettings();
    
        findDialog = 0;
    
        setAttribute(Qt::WA_DeleteOnClose);
        setWindowIcon(QIcon(":/images/Spreadsheet.ico"));
        setCurrentFile("");
    
        foreach (QWidget* win, QApplication::topLevelWidgets())
            if(MainWindow* mainWin = qobject_cast<MainWindow *>(win))
                mainWin->updateRecentFileActions();
              
    }
    

    My code is a newer version of the book's. If any other section is needed I will post.
    After installing the program, it neither closes all open windows by exit nor prevents itself from opening the same file twice or more!
    What is the problem please?

    Thanks.



  • Not sure about the book. By looking at your explanation you can do the following.

    1. Inside the open slot, check if the file is already open. If open, you don't open it again.
    2. Closing - You maintain the list of file handles which are open already. During the close Action, close the file handles. Also close the appropriate editor window as well.


  • @tomy said in What code to use in an app to make it not load the same file twice:

    it neither closes all open windows by exit

    What does it mean ?
    The app doesn' t exit ?
    If it does, it's meant that all the windows are closed.

    In your MainWindow do:

    void MainWindow::closeEvent(QCloseEvent *event)
    {qDebug()<<__FUNCTION__;
        if (okToContinue()) {
            writeSettings();
            event->accept();
        } else {
            event->ignore();
        }
    }
    

    A message should appear in the Application ouput panel when the window is closed.

    I look at your projet, unfortunatly, you use Qt 4 (like in the book) which is obsolete for years now.
    Until Qt 4.8 is mandatory to you, you should migrate to Qt 5.



  • @dheerendra

    1. Inside the open slot, check if the file is already open. If open, you don't open it again.

    All saving and opening files end in a slot named "setCurrecntFile". If I declare a vector<QString> and put each newly saving/opening file into it, but checking for its existence beforehand, I might ab able not to open the previously opened files. And by closing each file, put its name out of the vector. Ideas?

    1. Closing - You maintain the list of file handles which are open already. During the close Action, close the file handles. Also close the appropriate editor window as well.

    Let's think we will do it and also take advantages of the vector I mentioned, what's the role of the static void closeAllWindows(); function (in qapplication.h), then? Look at the exitAction's connect please.



  • @mpergand

    void MainWindow::closeEvent(QCloseEvent *event)
    {qDebug()<<FUNCTION;
    if (okToContinue()) {
    writeSettings();
    event->accept();
    } else {
    event->ignore();
    }
    }

    A message should appear in the Application ouput panel when the window is closed.
    

    I can't open more than one file using the program running by Qt Creator. I need to make an installer as before and test opening many files and closing all by exit. But by Qt Creator it showed this message for both close and exit:
    MainWindow.exe exited with code 0

    I look at your projet, unfortunatly, you use Qt 4 (like in the book) which is obsolete for years now.
    Until Qt 4.8 is mandatory to you, you should migrate to Qt 5.

    It's a very important subject for me. I want to be aware of the sections that can be replaced with new versions. And I will do that. If possible, please tell me which parts are of qt 4 and we have good replacements in Qt 5 form them.

    Incidentally, the app I created and installed looks very old-fashioned!! you're right.



  • @tomy said in What code to use in an app to make it not load the same file twice:

    Qt Creator it showed this message for both close and exit:
    MainWindow.exe exited with code 0

    It's normal and prove that the window is closed when the prog exits.

    Do you really want to develop a multi documents/windows capable application ?



  • @mpergand

    Do you really want to develop a multi documents/windows capable application ?

    Isn't this that? I can open as many files as I like using that app either by double clicking or using the open action.

    Aren't you talking about MDI (Multiple Document Interface)?



  • Can you post a link with your the new version of your app, i'll take a look at your code.

    I think the following isn't suitable for multi windows app:

    MainWindow* mainWin = new MainWindow;
     mainWin->show();
    

    This kind of paradigm is window centred.
    You need a central master object, a subclass of QApplication is a good candidate.

    For example:

    foreach (QWidget* win, QApplication::topLevelWidgets())
          if(MainWindow* mainWin = qobject_cast<MainWindow *>(win))
              mainWin->updateRecentFileActions();
    

    Why each window should be aware of other one's ?
    That's bad design.

    QStringList MainWindow::recentFiles;
    

    static method all around ...

    All that stuff should be managed by your QApplication subclass.

    My two cents ...

    [EDIT]
    For a good example of a multi documents app, you can look at the DemoBrowser:
    https://doc.qt.io/qt-5/qtwebengine-webenginewidgets-demobrowser-example.html



  • @mpergand

    Can you post a link with your the new version of your app, i'll take a look at your code.

    It's much (90%) like the one I posted in the first post. I just added some more context menu actions, opening the files using double clicking, an so on.

    I think the following isn't suitable for multi windows app:

    MainWindow* mainWin = new MainWindow;
     mainWin->show();
    

    This kind of paradigm is window centred.
    You need a central master object, a subclass of QApplication is a good candidate.

    How to create instances of the class MainWindow using this method?

    For example:

    foreach (QWidget* win, QApplication::topLevelWidgets())
          if(MainWindow* mainWin = qobject_cast<MainWindow *>(win))
              mainWin->updateRecentFileActions();
    

    Why each window should be aware of other one's ?
    That's bad design.

    I added it because it was suggested by the book. To be honest I don't understand all of this completely.

    QStringList MainWindow::recentFiles;
    

    static method all around ...

    It was also suggested by the book. To be honest I can't figure out why we need to have the same recent files list in each opened file. I might remove these two parts.

    All that stuff should be managed by your QApplication subclass.

    I don't know what class you mean by that QApplication subclass.

    My two cents ...

    Thank you.

    [EDIT]
    For a good example of a multi documents app, you can look at the DemoBrowser:
    https://doc.qt.io/qt-5/qtwebengine-webenginewidgets-demobrowser-example.html

    I wasn't aware that there are these source codes on Documentations! I will go for that although it's a different app and has completely different purposes.
    By the way, isn't here the page of all source codes offered by Docs?



  • There are a lot of examples in your Qt install folder.

    My advice would be, don't try to reproduce exactly the code you see in books or code examples.
    The main point is to understand how things work and then go your own way.



  • @mpergand

    My advice would be, don't try to reproduce exactly the code you see in books or code examples.

    I just want to master the things.

    I go for the vector solution. If any ideas in this case or other things, I'd glad to hear that, guys.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.