Problems in Implementing Save Feature in Javascript app using Qt



  • Hi,

    I have an application written in JavaScript. I am trying to port it on on Maemo Platform using Qt.

    I am facing problems in implementing "Save feature" to it. Whatever data I write on my application is saved in a "string" in a dosave() function of my JavaScript file.

    I want to know the ways I can save the data returned by the JavaScript function and can get back same thing on my file when I open it.

    I am using evaluateJavaScript() function to interact with JavaScript. Here is my code :

    [code]
    void Test::on_pushButton2_clicked()
    {

        QVariant name;
    
        QString fileName = QFileDialog::getSaveFileName(this,
                 tr("Save file"), "",
                 tr("Myapp (*.app);;All Files (*)"));
    
             if (fileName.isEmpty())
                 return;
             else {
                 QFile file(fileName);
                 if (!file.open(QIODevice::WriteOnly)) {
                     QMessageBox::information(this, tr("Unable to open file"),
                         file.errorString());
                     return;
                 }
    
              
           name = webView->page()->mainFrame()->evaluateJavaScript("dosave()");
    }
    

    }
    [/code]

    I am able to save my file but when I open it , I get blank file again with no data in it.
    I am not able retrieve data. What approach should I follow ?

    Kindly suggest some solution to my problem.
    What are the ways I can save the data returned by the JavaScript function and can get back same thing on my file when I open it.

    How can I implement data structures or Hash table in Qt programming, where I can save the strings returned and then use them in function created in Javascript used to open my saved files ?
    Kindly suggest some solutions.


  • Moderators

    You are not actually saving the contents of "name" into your file "file" in this snippet. Is that a cut and paste error?



  • No Sir, Its not a cut paste error, in fact I am making blunder by doing this.

    name is a QVariant variable. However, dosave() function in above code returns all the content in string format as written in my javaScript file.

    Would that effect when I save contents of "name" into my file "file"?

    How can I use QDataStream object to save contents of "name" in my file ? I read code of Address Book Example in Qt. Kindly help me on the same line.

    To open my saved file, I use open() function defined in my javascript file in which I just need to pass this string having all the contents.

    code snippet for that is :

    [code]

    webView->page()->mainFrame()->evaluateJavaScript("open(name)");

    [/code]

    But here is a mistake, I guess. name is again a QVariant type. How can I convert QVariant type to "string" type so that it could be passed to open() function ?

    Kindly help. I am a newbie at Qt programming and facing problems in implementing Save and Loading features.


  • Moderators

    Sorry, I do not understand what you want to get done.

    Are you trying to use C++ code to store/restore some data that you get from a javascript method? What is the javascript "open(name)" snippet supposed to do?



  • Yeah, exactly. I am trying to use C++ code to store/restore some data that you get from a javascript method. I have defined dosave()function in my javascript file which saves the contents in a "string" and returns it.

    Similarly, I have open() function defined in javascript code, in which this particular string is passed and it writes the content back to the file I want to open.

    Now, I want to implement Save and Load feature using Qt Programming. I built an GUI interface having these two buttons "Save" and "Open". I can save the file but I don't see contents I wrote on it when I open it.

    I wrote similar code when open button is clicked. Here is the code:
    [code]

    void Test::on_pushButton3_clicked()
    {
    QString fileName = QFileDialog::getOpenFileName(this,
    tr("Open File"), "",
    tr("My App (.app);;All Files ()"));

         if (fileName.isEmpty())
             return;
         else {
    
             QFile file(fileName);
    
             if (!file.open(QIODevice::ReadOnly)) {
                 QMessageBox::information(this, tr("Unable to open file"),
                     file.errorString());
                 return;
             }
    
             webView->page()->mainFrame()->evaluateJavaScript("open(name)");
         }
    

    }

    [/code]

    Kindly correct me where I am going wrong.

    Do I need to use some kind of data structure or hash table ? How can I use them. What are the ways to do it. ? Can I use QDataStream as it was used in Address Book demo application ?


  • Moderators

    Oh, you can do all kinds of tricks to store data:-) You could use a QVariantMap for a pretty generic hierarchical key/value system, etc. or just store a single serialized string. You could of course also serialize to XML or binary streams. The best way to serialize data of course depends on your requirements.

    What is your most recent snippet of code supposed to do? It opens a file and then calls the open function in javascript with a (undefined?) name variable. Notice that name is not defined in C++ and that you can not mix and match variables from Javascript and C++. So even if name was defined in C++ you could not use it in Javascript! I think you will need to do something like this:

    @
    QString name = file.readAll();
    webView->page()->mainFrame()->evaluateJavaScript("open("%1")").arg(name);
    @

    to actually pass the string into Javascript world. This of course assumes you have serialized all your data into one string.

    Hint: Renaming your buttons to something more descriptive than "pushButton3" will make your code way easier to understand;-)



  • Hi,

    Thanks a lot. That info was useful.

    I implemented some changes in my code, I am using QMap container class to store serialized data. In that ,I am using fileName as_ key_ and serialized data as value to that key (returned in the form of string by Javascript function) which I wrote in my file.

    However, I am still facing the same problem. My file gets saved in the hard disk but when I open it, I am not able see my data. I had no error while compiling, still I am facing the same problem. Kindly help.

    My code for saving the content.
    [code]
    void Test::save_button_clicked()
    {
    ///I have declared "content" as a global QVariant type and data as a global QString type.

    content = webView->page()->mainFrame()->evaluateJavaScript("save()");
       data = content.toString();  /// Have converted the QVariant variable to QString type.  
       QString fileName = QFileDialog::getSaveFileName(this,
                 tr("Save File "), "",
                 tr("Myapp (*.app);;All Files (*)"));
    
             if (fileName.isEmpty())
                 return;
             else {
                 QFile file(fileName);
        contacts.insert(fileName,data);  /// Here I am storing the data. I have declared "contacts" while the class "Test" itself.
    
                 if (!file.open(QIODevice::WriteOnly)) {
                     QMessageBox::information(this, tr("Unable to open file"),
                         file.errorString());
                     return;
                 }
    
             }   
    

    }
    [/code]

    My code for opening the saved file.

    [code]
    void Test::open_button_clicked()
    {
    QString fileName = QFileDialog::getOpenFileName(this,
    tr("Open File"), "",
    tr("Myapp (.app);;All Files ()"));

    QMap<QString, QString>::iterator i = contacts.find(fileName);
    if (i != contacts.end())
             i++;
    
         if (i == contacts.end())
             i = contacts.begin();
    
         data = i.value();  //// Do I still need to use file readall() function ?
    webView->page()->mainFrame()->evaluateJavaScript(QString("open(\"%1\")").arg(data));
    
         QFile file&#40;fileName&#41;;
            if (!file.open(QIODevice::ReadOnly) {
                 QMessageBox::information(this, tr("Unable to open file"),
                     file.errorString());
                 return;
             }        
    

    }
    [/code]

    Where am I going wrong ?

    QMap must return the serialized data I stored as key value . Kindly correct me if I am wrong.


  • Moderators

    Opening and (implicitly) closing a file does not make data show up in it! You need to actually write something into it.



  • Hello Sir,

    Can you kindly explain in detail what changes should I make in my code, or how should I go forward now with the current code to accomplish this save feature.

    As I told earlier, whatever I write in my application (for example : "My name is John"), save() function in my javascript script file (where whole code of application is written) stores it as a serialized data.

    open() function defined in the same file uses the same serialized data and writes it to the respective file.

    Can you tell me where am I going wrong ? . So that I can implement changes to it. Kindly suggest a solution.


  • Moderators

    Sorry, I do not understand your code at all.

    • I am pretty sure you are not saving anything into the file. Check the generated file and make sure that the data you expect is there.

    • QVariant::toString() is not meant to serialize data but to convert simple data into strings when possible. It will most likely fail with complex data found in a typical QVariantMap and return a empty string.

    • What type is "contacts"? I guess a QVariantMap or something... You are generating a key "filename" there and put some data into that (not into any file).

    • You do not read any data from the file in the open_button_clicked method. So even if you had managed to put data into a file you will not be able to restore it.

    • No idea what you want to do with the iterator... There is no loop, so you are not iterating over the contacts data. You find the position of the element you care about, then move to the next element. If you are then at the end of the data structure you move to the first element... yeap, that works, but only if there is exactly one element in your structure.

    • You use the data found in that structure to call into javascript.

    I would suggest doing the following:

    • remove "contacts". I do not see why that is needed.

    • Print in Javascript what the save function returns. Check that it is what you expect. Fix the Javascript till it does return what you want.

    • Print content and data variables in save_button_clicked. Make sure it is what you expect. Fix the code till it does.

    • Open a file, write a static string into it, close it again. Check that the file is really created and contains the string you wrote into it.

    • Replace the static string with the data. Check that the file is still created and contains the expected data. Fix the code till it does.

    Only when all this works I would continue with the open_button_clicked method, using a similar approach. No, I will not provide code: Coming up with this code is your job, not mine:-)

    Best Regards,
    Tobias


Log in to reply
 

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