Dmitry Bubnenkov
Dmitry Bubnenkov

Reputation: 9859

How to add File name at recently opened file File menu

I want to write a QML app that adds the latest opened files from FileDialog to the main menu. I'm currently following this documentation example but the problem is that I can't understand how to pass the file name of an opened file.

import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    menuBar : MenuBar
    {
        Menu
        {
            id: recentFilesMenu
            Instantiator
                {
                    model: recentFilesMenu
                    MenuItem
                    {
                        text: model.fileName // I neeed to pass name of opned file here
                    }
                    onObjectAdded: recentFilesMenu.insertItem(index, object)
                }

            title: "File"
            MenuItem
            {
                text: "Open"
                onTriggered: fileDialog.visible = true

            }


            MenuItem
            {
                text: "Exit"
            }
        }


    }

    FileDialog
        {
            id: fileDialog
            title: "Oooopen"
            onAccepted:
            {
              // Here is problem
            recentFilesMenu.objectName = fileDialog.fileUrls
            }
        }
}

Upvotes: 1

Views: 899

Answers (3)

Francisco Hernandez
Francisco Hernandez

Reputation: 312

You probably have a finite number of recent files that you want to display. That being said, you can implement x number of MenuItems and set the text to QStringList[i] implemented as a Q_PROPERTY in a C++ class. Then, you can manipulate the QStringList elements(size, order) on your C++ class.

Upvotes: 0

BaCaRoZzo
BaCaRoZzo

Reputation: 7692

According to the documentation, Instantiator accepts the most common types of models - both C++ and QML ones. In the documentation example such an information is missing, probably to not force the usage of a specific one. An actual implementation can relay on ListModel. In this case the model would expose a fileName role used as the actual menu item.

Following this approach the result would be something like the following code. Mind that the urls are prepended with information which can be easily removed (see for instance this answer).

import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    menuBar : MenuBar {

        Menu {
            id: recentFilesMenu

            title: "File"

            MenuItem {
                text: "Open"
                onTriggered: fileDialog.visible = true
            }

            MenuSeparator { }

            Instantiator {
                model: ListModel { id: files }

                MenuItem { text: fileName }

                onObjectAdded: recentFilesMenu.insertItem(index, object)
                onObjectRemoved: recentFilesMenu.removeItem(object)
            }

            MenuSeparator { visible: files.count > 0 }

            MenuItem { text: "Exit" }
        }
    }

    FileDialog {
        id: fileDialog
        title: "Open"
        onAccepted: {
            for(var i = 0; i < fileDialog.fileUrls.length; ++i)
                files.append({fileName: fileDialog.fileUrls[i]})
        }
    }
}

Upvotes: 2

phyatt
phyatt

Reputation: 19112

There is a widgets version of this kind of feature:

http://doc.qt.io/qt-5/qtwidgets-mainwindows-recentfiles-example.html

But the descriptive help is non-existent. Looking through the code here:

http://doc.qt.io/qt-5/qtwidgets-mainwindows-recentfiles-mainwindow-cpp.html

You will see that it stores a QStringList of a list of recent files in QSettings, and loads everything into an array of QActions.

Follow through the mainWindow.cpp for all the references to

enum { MaxRecentFiles = 5 };
QAction *recentFileActs[MaxRecentFiles];

And you should have some good ideas about how to do something similar in QML.

Hope that helps.

Upvotes: 1

Related Questions