¿Cómo agrego dinámicamente una pestaña a las pestañas?

10

Estoy tratando de agregar una nueva pestaña al componente de pestañas con el código a continuación.

Cuando se ejecuta, no se informa ningún error, pero no se muestran pestañas adicionales. He intentado usar pestañas y pestañas .__ tabsModel como padre pero no se muestran pestañas adicionales.

import QtQuick 2.0
import QtQuick.LocalStorage 2.0
import Ubuntu.Components 0.1

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    id: mainView
    objectName: "mainView"
    applicationName: "news-feed"

    width: units.gu(100)
    height: units.gu(75)

    Tabs {
        id: tabs
        anchors.fill: parent

        Component.onCompleted: {
            mainView.initializeDB();
            mainView.saveFeed("BBC News","http://feeds.bbci.co.uk/news/rss.xml");
            mainView.saveFeed("Jono Bacon","http://www.jonobacon.org/?feed=rss2");
            mainView.saveFeed("The Register", "http://www.theregister.co.uk/headlines.atom");
            fillTabs();
        }

        tools: ToolbarActions {
            Action {
                objectName: "action"

                iconSource: Qt.resolvedUrl("avatar.png")
                text: i18n.tr("Tap me!")

                onTriggered: {
                    label.text = i18n.tr("Toolbar tapped")
                }
            }
        }

        // First tab begins here
        Tab {
            id: tabFrontPage
            objectName: "tabFrontPage"

            title: i18n.tr("Front Page")

            // Tab content begins here
            page: Page {
                Column {
                    anchors.centerIn: parent
                    Label {
                        id: labelFrontPage
                        text: i18n.tr("This will be the front page \n An aggregation of the top stories from each feed")
                    }
                }
            }
        }
    }

    function fillTabs() {
        var db = getDatabase();
        db.transaction(function(tx) {
            var rs = tx.executeSql('SELECT * FROM feeds;');
            if (rs.rows.length > 0) {
                for(var i = 0; i < rs.rows.length; i++) {
                    var feedTab = Qt.createQmlObject('import QtQuick 2.0;import Ubuntu.Components 0.1;Tab {anchors.fill: parent;objectName: "Tab";title: i18n.tr("Tab");page: Page {anchors.margins: units.gu(2);Column {anchors.centerIn: parent;Label {id: label;objectName: "label";text: i18n.tr("Tab");}}}}',tabs,"feedTab");
                }
            } else {
                res = "Unknown";
            }
        })
    }
    //Storage API
    function getDatabase() {
        return LocalStorage.openDatabaseSync("news-feed","1.0","StorageDatabase",10000)
    }

    //Initialise DB tables if not already existing
    function initializeDB() {
        var db = getDatabase();
        db.transaction(function(tx) {
            //Create settings table if not existing
            tx.executeSql('CREATE TABLE IF NOT EXISTS settings(setting TEXT UNIQUE, value TEXT)');
            tx.executeSql('CREATE TABLE IF NOT EXISTS feeds(feedName TEXT UNIQUE, feedURL TEXT UNIQUE)')
        });
    }

    //Write setting to DB
    function setSetting(setting,value){
        //setting: string - setting name (key)
        //value: string - value
        var db = getDatabase();
        var res = "";
        db.transaction(function(tx) {
            var rs = tx.executeSql('INSERT OR REPLACE INTO settings VALUES (?,?);',[setting,value]);
            //console.log(rs.rowsAffected)
            if(rs.rowsAffected > 0) {
                res = "OK";
            } else {
                res = "Error";
            }
        })
        return res;
    }

    //Read setting from DB
    function getSetting(setting) {
        var db = getDatabase();
        var res="";
        db.transaction(function(tx) {
            var rs = tx.executeSql('SELECT value FROM settings WHERE setting=?;', [setting]);
            if (rs.rows.length > 0) {
                res = rs.rows.item(0).value;
            } else {
                res = "Unknown";
            }
        })
        return res;
    }

    function saveFeed(feedName, feedURL) {
        var db = getDatabase();
        var res = "";
        db.transaction(function(tx){
            var rs = tx.executeSql('INSERT OR REPLACE INTO feeds VALUES (?,?)',[feedName,feedURL]);
            //console.log(rs.rowsAffected)
            if (rs.rowsAffected > 0) {
                res = "OK";
            } else {
                res = "Error";
            }
        })
        return res;
    }

    //Return a single feed
    function getFeed(feedName) {
        var db = getDatabase();
        var res = "";
        db.transaction(function(tx) {
            var rs = tx.executeSql('SELECT feedURL FROM feeds WHERE feedName=?;', [feedName]);
            if (rs.rows.length > 0) {
                res = rs.rows.item(0).feedURL;
            } else {
                res = "Unknown";
            }

        })
        return res;
    }

    //Return all feeds and urls
    function getFeeds() {
        var db = getDatabase();
        var res = "";
        db.transaction(function(tx) {
            var rs = tx.executeSql('SELECT * FROM feeds;');
            if (rs.rows.length > 0) {
                return rs;
            } else {
                res = "Unknown";
            }
        })
        return res;
    }
}
Morchuboo
fuente
1
Esta pregunta puede estar ligeramente fuera de tema aquí. Recomendaría una respuesta más rápida y mejor para preguntar esto en StackOverflow.
lordqwerty
3
La pregunta es totalmente sobre el tema. Hemos estado usando Ask Ubuntu para preguntas de desarrollo de aplicaciones con bastante éxito desde hace bastante tiempo.
David Planella
También - el problema puede estar relacionado específicamente con los componentes ubuntu-
Morchuboo
voto cerrado hecho accidentalmente, lo siento amigos.
r 26dʒɑ

Respuestas:

5

Me temo que agregar pestañas dinámicamente actualmente no es posible

El equipo del SDK me dice que esta es una limitación del tipo VisualItemModel (que usa el componente Tabs ), ya que no permite agregar hijos dinámicamente.

Hay un error abierto para realizar un seguimiento de este problema .

David Planella
fuente
todavía hay trabajo por delante ;-)
NilsB
¿Hay un boleto que uno pueda rastrear?
carga útil
Pensé tanto. Lo solucioné creando todo el componente contenedor de pestañas y todos los componentes de pestaña contenidos en una función de JavaScript y luego agregándolo con mainView como padre. Horriblemente hackey pero funciona: P
Morchuboo
1
@payload, ahora no hay un error para hacer un seguimiento de esto, pero siéntase libre de abrir uno para que el equipo del SDK eche un vistazo a: bugs.launchpad.net/ubuntu-ui-toolkit/+filebug
David Planella
@payload, alguien ya había registrado un ticket con este problema: bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1124071 . Mi solución para usar la función Qt.createQmlObject con la colección de pestañas y todos los niños se pueden ver aquí: pastebin.com/dmyPkyyX Realmente no es muy elegante y la cadena se vuelve inmanejable rápidamente pero funciona. Vea la función fillTabs ().
Morchuboo
0

Aquí hay una solución alternativa de ejemplo.

Este método da como resultado que casi toda la interfaz gráfica de usuario se especifique en una cadena y se vuelva desordenada rápidamente, pero funcionará hasta que la característica para agregar a VisualItemModel se implemente en sentido ascendente.

Este es el comienzo de un lector rss con el que estoy jugando. Si lo pega en un archivo qml vacío, debería funcionar bien. (es posible que deba instalar libqt5sql5-sqlite y qtdeclarative5-localstorage-plugin. Están en las imágenes del teléfono pero no se instalaron con la instalación del SDK).

import QtQuick 2.0
import QtQuick.LocalStorage 2.0
import Ubuntu.Components 0.1

/*!
    \brief MainView with Tabs element.
       First Tab has a single Label and
       second Tab has a single ToolbarAction.
*/

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    id: mainView
    objectName: "mainView"
    applicationName: "news-feed"

    width: units.gu(100)
    height: units.gu(75)

    tools: ToolbarActions {
    Action {
        objectName: "action"

        iconSource: Qt.resolvedUrl("avatar.png")
        text: i18n.tr("Tap me!")

        onTriggered: {
            label.text = i18n.tr("Toolbar tapped")
        }
    }
    }

    Component.onCompleted: {
    mainView.initializeDB();
    mainView.saveFeed("BBC News","http://feeds.bbci.co.uk/news/rss.xml");
    mainView.saveFeed("Jono Bacon","http://www.jonobacon.org/?feed=rss2");
    mainView.saveFeed("The Register", "http://www.theregister.co.uk/headlines.atom");
    fillTabs();
    }

    Tabs {
    id: initialtabs
    anchors.fill: parent

    tools: ToolbarActions {
        Action {
            objectName: "action"

            iconSource: Qt.resolvedUrl("avatar.png")
            text: i18n.tr("Tap me!")

            onTriggered: {
                label.text = i18n.tr("Toolbar tapped")
            }
        }
    }

    // First tab begins here
    Tab {
        id: tabFrontPage
        objectName: "tabFrontPage"

        title: i18n.tr("Front Page")

        // Tab content begins here
        page: Page {
            Column {
                anchors.centerIn: parent
                Label {
                    id: labelFrontPage
                    text: i18n.tr("This will be the front page \n An aggregation of the top stories from each feed")
                }
            }
        }
    }
    }


    function fillTabs() {
    initialtabs.destroy();
    var objStr = "import QtQuick 2.0;import Ubuntu.Components 0.1;import QtQuick.XmlListModel 2.0;Tabs{id:tabs;anchors.fill:parent;"
    var db = getDatabase();
    db.transaction(function(tx) {
        var rs = tx.executeSql('SELECT * FROM feeds;');
        if (rs.rows.length > 0) {
            for(var i = 0; i < rs.rows.length; i++) {
                objStr += "Tab {id:tab" + i + ";anchors.fill:parent;title:'" + rs.rows.item(i).feedName + "';property string source: '" + rs.rows.item(i).feedURL + "';page: Page {anchors.margins: units.gu(2);Column {anchors.centerIn: parent;Label{text:tab" + i + ".source;}}}}";
            }
            objStr += "}";
            var cmpTabs = Qt.createQmlObject(objStr,mainView,"tabsfile");
        } else {
            res = "Unknown";
        }
    })
    }

    //Create tabs for each feed
    function createTabs() {
    var feeds = getFeeds();
    for (var i = 0; i < feeds.length; i++){
        //Add tab for each feed.
        //Cannot be done with existing API

    }
    }

    //Storage API
    function getDatabase() {

    return LocalStorage.openDatabaseSync("news-feed","1.0","StorageDatabase",10000)
    }

    //Initialise DB tables if not already existing
    function initializeDB() {
    var db = getDatabase();
    db.transaction(function(tx) {
        //Create settings table if not existing
        tx.executeSql('CREATE TABLE IF NOT EXISTS settings(setting TEXT UNIQUE, value TEXT)');
        tx.executeSql('CREATE TABLE IF NOT EXISTS feeds(feedName TEXT UNIQUE, feedURL TEXT UNIQUE)')
    });
    }

    //Write setting to DB
    function setSetting(setting,value){
    //setting: string - setting name (key)
    //value: string - value
    var db = getDatabase();
    var res = "";
    db.transaction(function(tx) {
        var rs = tx.executeSql('INSERT OR REPLACE INTO settings VALUES (?,?);',[setting,value]);
        //console.log(rs.rowsAffected)
        if(rs.rowsAffected > 0) {
            res = "OK";
        } else {
            res = "Error";
        }
    })
    return res;
    }

    //Read setting from DB
    function getSetting(setting) {
       var db = getDatabase();
       var res="";
       db.transaction(function(tx) {
     var rs = tx.executeSql('SELECT value FROM settings WHERE setting=?;', [setting]);
     if (rs.rows.length > 0) {
          res = rs.rows.item(0).value;
     } else {
         res = "Unknown";
     }
      })
      // The function returns “Unknown” if the setting was not found in the database
      // For more advanced projects, this should probably be handled through error codes
      return res;
    }

    function saveFeed(feedName, feedURL) {
    var db = getDatabase();
    var res = "";
    db.transaction(function(tx){
        var rs = tx.executeSql('INSERT OR REPLACE INTO feeds VALUES (?,?)',[feedName,feedURL]);
        //console.log(rs.rowsAffected)
        if (rs.rowsAffected > 0) {
            res = "OK";
        } else {
            res = "Error";
        }
    })
    return res;
    }

    //Return a single feed
    function getFeed(feedName) {
    var db = getDatabase();
    var res = "";
    db.transaction(function(tx) {
        var rs = tx.executeSql('SELECT feedURL FROM feeds WHERE feedName=?;', [feedName]);
        if (rs.rows.length > 0) {
            res = rs.rows.item(0).feedURL;
        } else {
            res = "Unknown";
        }

    })
    return res;
    }

    //Return all feeds and urls
    function getFeeds() {
    var db = getDatabase();
    var res = "";
    db.transaction(function(tx) {
        var rs = tx.executeSql('SELECT * FROM feeds;');
        if (rs.rows.length > 0) {
            return rs;
        } else {
            res = "Unknown";
        }
        })
    return res;
    }
}
Morchuboo
fuente