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

Immediatly updating data in qml tableView



  • Hello, guys! I need your help.
    I use qml table view for rendering data which I get from video file.
    For this task I have Parser class, from which I call function extractDataWrapper() for file parsing.
    I call extractDataWrapper() from ApplicationWindow by button click
    In general, all looks something like this

    parser.h
    class Parser : public QObject
    {
    Q_OBJECT
    ...
    public:
    Q_INVOKABLE void extractDataWrapper();
    ...
    }
    

    In main.cpp I create object from this class, register types and so on.

    #include "parser.h"
    ...
    ...
    
    int main(int argc, char *argv[])    
    {
        QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QApplication app(argc, argv);
        QQmlApplicationEngine engine;
        Parser parser_;
    
        qmlRegisterUncreatableType<Parser>("Parser", 1, 0, "Parser", "");
        engine.rootContext()->setContextProperty("Parser", &parser_);
        engine.load(QUrl(QStringLiteral("qrc:/qml/interface/main.qml")));
        if (engine.rootObjects().isEmpty()) return -1;
        return app.exec();
    }
    

    I use my class NoteModel inherited from QAbstractListModel as model.
    NoteModel.h

    class Note {
    ...
    // objects for NoteModel 
    ...  
    };
    
    class NoteModel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        ExtractorNoteModel(QObject *parent = 0);
        ~ExtractorNoteModel() override;
        
        void addNote(const ExtractorNote* note);
    
        int rowCount(const QModelIndex & parent = QModelIndex()) const override;
        QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
        QHash<int, QByteArray> roleNames() const override;
    private:
        QList<Note*> notes_;
    };
    

    With addNote() I add data to model like this:
    NoteModel.cpp

    #include "NoteModel"
    ...
    ...
    
    void NoteModel::addNote(const Note *note) {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        notes_ << const_cast<Note*>(note);
        endInsertRows();
    }
    

    With call parser_.extractDataWrapper() inside this function I set data to model like this
    parser.cpp

    #include "parser.h"
    
    void Parser::extractDataWrapper(){
    …
       while(true){
            ...
            NoteModel* ptr;
            ptr->addNote(new Note(/* my arguments */))
            ...
       }
    ...
    }
    

    Between calls ptr->addNote(new Note(/* my arguments */)) some time goes by.
    After parser_.extractDataWrapper() finished I get updated table view my main.qml file
    In common interface looks like this
    ![alt text](272e0fa7-89ad-41cb-8575-485a58cee218-image.png image url)
    But view updates all entries only after parser_.extractDataWrapper() is finished.
    The question is:
    Can I update table view immediately after new entry was added to NoteModel, i.e one by one entry
    and if can what I need to do?
    Any help would be helpful.
    Thanks!



  • Ok, I've got it. Just need use QThread or std::thread.
    Without another thread interface will be updated only after function finished execution and return control back to renderer engine.
    i.e. need call parser_.extractDataWrapper() in another thread, and all will be ok.
    example:
    https://stackoverflow.com/questions/18232602/pass-value-by-reference-to-a-thread-and-modify


Log in to reply