Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Mapper fails to submit: QDataWidgetMapper, QSqlRelationalTableModel
Forum Updated to NodeBB v4.3 + New Features

Mapper fails to submit: QDataWidgetMapper, QSqlRelationalTableModel

Scheduled Pinned Locked Moved General and Desktop
7 Posts 3 Posters 6.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • X Offline
    X Offline
    Xionbox
    wrote on last edited by
    #1

    I am facing a problem with a C++ Qt4 Widget. This widget is to be used for adding rows into a SQLite database. Here are the database tables which are used in this code snippet:
    @
    CREATE TABLE 'statuses' ('id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE , 'name' VARCHAR(50) NOT NULL UNIQUE , 'bgcolor' VARCHAR(6) NOT NULL DEFAULT ffffff, 'fgcolor' VARCHAR(6) NOT NULL DEFAULT 000000)
    CREATE TABLE 'addresses' ('id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE , 'name' VARCHAR(50) NOT NULL UNIQUE , 'country' VARCHAR(25), 'town' VARCHAR(50), 'postal_code' VARCHAR(10), 'street' TEXT check(typeof('street') = 'text') , 'ref' VARCHAR(5) NOT NULL , 'status_id' INTEGER NOT NULL, FOREIGN KEY(status_id) REFERENCES statuses(id))
    @
    The code I wrote, which follows exactly the Qt tutorial [url=http://doc.qt.nokia.com/latest/sql-sqlwidgetmapper.html]SQL WidgetMapper[/url], follows:
    @
    CreateAddressDialog::CreateAddressDialog(QWidget parent) :
    QDialog(parent),
    ui(new Ui::CreateAddressDialog)
    {
    ui->setupUi(this);
    /
    Set up "buddies" */
    ui->nameLabel->setBuddy(ui->nameLineEdit);
    ui->refLabel->setBuddy(ui->refLineEdit);
    ui->townLabel->setBuddy(ui->townLineEdit);
    ui->streetLabel->setBuddy(ui->streetLineEdit);
    ui->countryLabel->setBuddy(ui->countryLineEdit);
    ui->postalCodeLabel->setBuddy(ui->postalCodeLineEdit);
    ui->statusLabel->setBuddy(ui->statusCB);

    /* Set up status model */
    ui->statusCB->clear();
    statusModel = new QSqlRelationalTableModel(this, backbone::instance()->db);
    statusModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
    statusModel->setTable("addresses");
    int statusFieldId = statusModel->fieldIndex("status_id");
    /***** Warning: after next instruction fieldIndex('status_id') will return -1. */
    statusModel->setRelation(statusFieldId,QSqlRelation("statuses", "id", "name"));
    statusModel->select();
    relModel = statusModel->relationModel(statusFieldId);
    ui->statusCB->setModel(relModel);
    ui->statusCB->setModelColumn(relModel->fieldIndex("name"));
    mapper = new QDataWidgetMapper(this);
    mapper->setItemDelegate(new QSqlRelationalDelegate(this));
    mapper->setModel(statusModel);
    mapper->addMapping(ui->refLineEdit, statusModel->fieldIndex("ref"));
    mapper->addMapping(ui->nameLineEdit, statusModel->fieldIndex("name"));
    mapper->addMapping(ui->statusCB, statusFieldId);
    

    }
    @
    The submission process is as simple as the following:
    @
    void CreateAddressDialog::accept()
    {
    if(ui->nameLineEdit->text().length() < 5){
    QMessageBox::critical(0, tr("Error"),tr("The name must be at least 5 characters long."), QMessageBox::Cancel);
    return;
    }else if(ui->refLineEdit->text().length() > 10){
    QMessageBox::critical(0, tr("Error"),tr("The reference may not be more than 10 characters long."), QMessageBox::Cancel);
    return;
    }else if(ui->statusCB->currentIndex() < 0){
    QMessageBox::critical(0, tr("Error"),tr("The item must have a status."), QMessageBox::Cancel);
    return;
    }
    qDebug() << mapper->submit();
    this->close();
    }
    @

    The problem, is that mapper->submit() failed ("false" is displayed). If I call the model's lastError, nothing shows up. The fields which are mapped to this mapper are the mandatory fields of the table (id excepted because it is marked as autoincrement).

    Any help is greatly appreciated as I really don't understand (and can't seem to find out) why this widget doesn't add anything to the database. Let me mention that I checked with a standard SQLite database viewer to be sure of the contents of the SQLite database were like.

    P.S.: You can browse the full code if you think it's needed to solve this problem on [url=https://code.google.com/p/invensile/source/browse/#svn/trunk]Google code[/url].

    Thanks in advance!

    1 Reply Last reply
    0
    • L Offline
      L Offline
      leon.anavi
      wrote on last edited by
      #2

      Hi,

      Please format your code in an appropriate way for this forum.

      If you are really following exactly the Qt tutorial about "SQL Widget Mapper Example":http://doc.qt.nokia.com/latest/sql-sqlwidgetmapper.html why don;t you download the provided files at the tutorial and using them to find and solve your problem?

      Regards,
      Leon

      http://anavi.org/

      1 Reply Last reply
      0
      • X Offline
        X Offline
        Xionbox
        wrote on last edited by
        #3

        Hi,

        Could you explain me what is the appropriate way for formatting code on Qt? There is no "help" link when posting a new thread (even when you're new on the forum just like me) nor bbcode cheat sheet. As for the HTML tags which showed (because I suppose that is what you are referring to), I added the [ code ] bb tags and the preview showed the post correctly. It was only upon submitting it that the < div > blocks showed up. I tried editing my post to remove them but they weren't in the message to be edited. I think it's a forum bug.

        As for the example, there is a major difference: my program is far more complex than that of the example. In fact, my main model which is used to display the results, is defined in the main window widget. The problem I am facing occurs in another widget (a widget with ok and close buttons). In C++, b.h can't include a.h if a.h already includes b.h . Since the main window calls this widget, I can't include the main window header in this widget. So the only solution would be to extract these variables into c.h and have both widgets include c.h . In my case, I prefered to simply recreate a QSqlRelationnalTable objects which is defined exactly as the one in the main window. In the main window, it works marvelously. For an obscure reason, it doesn't work in the widget. This is why I cam to get help.

        In addition, the example isn't complete and probably won't compile. If you look at the code (which I have for at least one hour total), some slots are called but never defined (neither in the .c nor in the header). That said, in my code, I follow line by line the procedure of the example.

        Thanks in advance for additional help.

        1 Reply Last reply
        0
        • L Offline
          L Offline
          leon.anavi
          wrote on last edited by
          #4

          [quote author="Xionbox" date="1304247979"]Could you explain me what is the appropriate way for formatting code on Qt? There is no "help" link when posting a new thread (even when you're new on the forum just like me) nor bbcode cheat sheet. [/quote]

          Please read the "Forum Help":http://developer.qt.nokia.com/wiki/ForumHelp About code wrapping check "this part of the help":http://developer.qt.nokia.com/wiki/ForumHelp#e3f82045ad0f480d3fb9e0ac2d58fb01

          [quote author="Xionbox" date="1304247979"]Hi,
          The problem I am facing occurs in another widget (a widget with ok and close buttons). In C++, b.h can't include a.h if a.h already includes b.h . Since the main window calls this widget, I can't include the main window header in this widget. So the only solution would be to extract these variables into c.h and have both widgets include c.h .[/quote]

          Can't you solve the issue using C++ forward declarations?

          Cheers,
          Leon

          http://anavi.org/

          1 Reply Last reply
          0
          • X Offline
            X Offline
            Xionbox
            wrote on last edited by
            #5

            Thank you for the help links. I've corrected my original post. I'll look into forward declaration and reply once I've tested that.

            1 Reply Last reply
            0
            • X Offline
              X Offline
              Xionbox
              wrote on last edited by
              #6

              I don't seem to be able to do a forward declaration and don't understand why. Maybe could someone help, here's what I do.

              In "createaddressdialog.h" (we can call it A.h), I added the following line:
              @
              namespace Ui {
              class MainWindow; // this is the new line
              class CreateAddressDialog;
              }
              @
              In "mainwindow.h" (we can call it B.h) I added the following line:
              @
              namespace Ui {
              class MainWindow; // this is the new line
              class CreateAddressDialog;
              }
              @

              Then in "createaddressdialog.cpp" (A.cpp), I added the following:
              @
              #include "createaddressdialog.h" // our A.h
              #include "mainwindow.h" // our B.h
              @

              Identically, I added the following in "mainwindow.cpp" (B.cpp):
              @
              #include "mainwindow.h" // our B.h
              #include "createaddressdialog.h" // our A.h
              @

              The problem is a major one: the program no longer compiles and display the following error.
              @
              In file included from main.cpp:3:0:
              mainwindow.h:55:5: error: ‘CreateAddressDialog’ does not name a type
              make: Leaving directory `xyz'
              make: *** [main.o] Error 1
              Exited with code 2.
              Error while building project Inventory
              When executing build step 'Make'
              @

              To make sure I was doing this properly, I had a look at this page: http://www.adp-gmbh.ch/cpp/forward_decl.html

              Any idea why this doesn't work?

              Additionally, is there a way to retrieve the lats error of "mapper->submit()"? I looked in the documentation and didn't seem to find anything. I also had a look at the model documentation (thinking of mapper->model->lastError() or something similar) but I didn't find anything there either.

              Thank you in advance.

              1 Reply Last reply
              0
              • F Offline
                F Offline
                Flesh
                wrote on last edited by
                #7

                I duplicated this problem, did you ever resolve it, if so how?

                I did note that in my code, the function returned true; but the database did not persist the data changes.

                Update: I tried submitAll on the model and it worked; I think that is your problem as well.

                Jeffrey Scott Flesher PhD
                http//LightWizzard.com/

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved