Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Data aware QPushbutton/QLabel



  • I am trying to map a cell that contains text from my database to the property of a widget. What I would like to do is the following :

    Having QLabel or a QPushbushButton whose text can be edited by the user of my application and once edited, it will update my SQLite database.
    

    I tried to make a QSqlTableModel from my database then map the widgets of my choice (a QPushButton in the example below) to them.

    I tried following this example from the documentation, but I seem to be missing something.

    The idea was to make the widgets data aware and when the user is done editing the widgets, I simply call the method submitAll() of my model.

    My database look like this : database.png

    The goal would be to, say, take the firstname "peter" from the db and use it for the text of the QPushButton.

    And here is my code :

        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName(QDir::currentPath() + "/todo.sqlite");
        if (!db.open()) {
        // something
        }
    
        QSqlQuery query;
    
        query.prepare("CREATE TABLE IF NOT EXISTS names (id INTEGER UNIQUE PRIMARY KEY, firstname VARCHAR(30), lastname VARCHAR(30))");
        query.exec();
    
        m_model = new QSqlTableModel(this, db);
        m_model->setEditStrategy(QSqlTableModel::OnManualSubmit);
        m_model->setTable("names");
        m_model->select();
    
        // Find the number of rows from the table
        query.exec("SELECT COUNT(*) FROM names");
        if(query.first())
            qDebug() << query.value(0).toInt() << Qt::endl;
    
    
        // do the mapping
        auto btn = new QPushButton;
        auto mapper = new QDataWidgetMapper(this);
        mapper->setModel(m_model);
        //mapper->setItemDelegate(new QSqlRelationalDelegate(this));
        qDebug() << m_model->fieldIndex("firstname");
        mapper->addMapping(btn, m_model->fieldIndex("firstname"));
    
        qDebug() << btn->text();
    


  • I solved my problem by calling the method toFirst() of the widget mapper



  • @Harsaith
    I don't know whether this whole thing will work for push buttons. But, since you haven't received any definitive answer, I am thinking you should try investigating widget properties.

    Per https://doc.qt.io/qt-5/qdatawidgetmapper.html#details

    Every time the current index changes, each widget is updated with data from the model via the property specified when its mapping was made.
    By default, each widget's user property is used to transfer data between the model and the widget. Since Qt 4.3, an additional addMapping() function enables a named property to be used instead of the default user property.

    If I understand right, the data in the model is sent to the mapped widget's user property. I imagine that for, say, a QLineEdit the mapping picks up the user property and sets the widget's text from that. Every QWidget has https://doc.qt.io/qt-5/qobject.html#setProperty

    Changing the value of a dynamic property causes a QDynamicPropertyChangeEvent to be sent to the object.

    I'm thinking you would connect for that on your QPushButton and have your slot change the button's text.

    You might look at the sources (woboq) of QDataWidgetMapper and see if does indeed listen for that signal and work that way.

    That's all I know! Please don't ask me for further information, I'm just suggesting you see whether I'm right and things work this way :)

    EDIT
    Oh, my post has just crossed with your post of what has worked for you! Anyway, maybe the above information will help for other things.... :)


Log in to reply