Skip to content
  • 0 Votes
    7 Posts
    416 Views
    B

    @hemang_1711 I have just gone back to your original post and I see again what originally confused me.

    If you recall, I asked about GraphParam, which you are trying to access in your QML. I looked for this in your model implementation, but your model does not have a role "GraphParam".

    You do have a role "GraphList", which seems to return the first element of the list member named GraphParam in the GraphModelItem struct in your implementation. Although GraphParam is the name of the struct member, QML does not know anything about this name. It only sees the names you have defined in your roles.

  • 0 Votes
    2 Posts
    324 Views
    JonBJ

    @Babs
    I presume that if you don't use d&d it's just a question of intercepting the keypresses in the list view and acting as desired on them, e.g. move an item at one index in the model to another index.

  • 0 Votes
    12 Posts
    2k Views
    T

    @fcarney I put the QAbstractItemModelTester in both my model, and my proxy model, and... no errors. I also swapped it to FailureReportingMode::Fatal to double check, and nothing. The endless calls to data from VXYModelMapper continue.

  • 0 Votes
    2 Posts
    345 Views
    E

    Still not sure what's the best design here.

  • 0 Votes
    3 Posts
    686 Views
    Q

    @VRonin said in How to propagate changes in SingleTon type custom QAbstractListModel on QML ListView?:

    @qml.newbie said in How to propagate changes in SingleTon type custom QAbstractListModel on QML ListView?:

    m_hackNewsList.append(HackNews{id, deleted, type, by, time, text, dead, parentId, pollId, kidsIdList, url, score, title, partsIdList, descendantCount});

    You need to call beginInsertRows/endInsertRows before/after m_hackNewsList.append(HackNews{id, deleted, type, by, time, text, dead, parentId, pollId, kidsIdList, url, score, title, partsIdList, descendantCount});

    I have now added these lines but even now it's not working. Could be down to something I did wrong in the main.cpp where I'm registering the model for qml? The main cpp file is as below.

    #include <QGuiApplication> #include <QQmlApplicationEngine> #include "NetworkRequestMaker.h" #include "HackNewsModel.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); NetworkRequestMaker testRequestMaker; qmlRegisterType<HackNewsModel>("Hacknews", 1, 0, "HackNewsModel"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
  • 0 Votes
    5 Posts
    2k Views
    C

    @SGaist

    When I remove the dataChanged(index,index) no update gets recognized.
    When I manually set the role vector to dataChanged(index, index, role) it behaves the same way as without the role specification (updates the current element, not the other ones).

    As per https://forum.qt.io/topic/39357/solved-qabstractitemmodel-datachanged-question/6 , I noticed that the other elements have to get a "recompute" signal and tried the following:

    bool setData(const QModelIndex & index, const QVariant & value, int role) override { // ... QModelIndex toIndex(createIndex(rowCount() - 1, index.column())); qDebug() << toIndex.row() << ',' << toIndex.column(); emit dataChanged(index, toIndex); }

    Which should've helped and would've made sense as it helped in the other thread, but it didn't trigger a recomputation :( I found this blogpost which discusses the problem at hand, but solves it in QML only because he would use the dataChanged signal in C++.

    EDIT: Marking this question as solved as my solution with the resetModel() worked. I had to implement a similar functionality with the same model, which was also dependent on the dataChanged signal, but it worked without resetModel. The only difference was that this functionality was encapsulated in a single "Item", e.g (color choose dialog -> change multiple textfields in the same "row").

  • 0 Votes
    3 Posts
    478 Views
    K

    @SGaist

    Thanks for pointing into that direction. It does work.

  • 0 Votes
    8 Posts
    2k Views
    VRoninV

    @milan said in How to implement checkstate for QAbstractItemModel or QAbstractListModel:

    I cannot hide the checkboxes

    if you return QVariant() for the CheckStateRole the checkbox will not appear in the default delegate (QStyledItemDelegate)

  • 0 Votes
    4 Posts
    511 Views
    Christian EhrlicherC

    Once again: When you add the role to your debug output you will for sure notice that the data for Qt::ToolTipRole is requested (and maybe Qt::BackgroundRole / TextRole because the item is repainted)

  • 0 Votes
    2 Posts
    2k Views
    romsharkovR

    After hours of google, trial and error I'm proud to finally have solved it myself as I am still pretty new to Qt!

    To help people with a similar problem I'll quickly sum up all I had to do to make it work:

    turn the internal QList<Message> into a QList<QSharedPointer<Message>>

    define a QMap<QString, QSharedPointer<Message>> to hold index ids to the individual messages

    when inserting, insert in the indexMap as well

    define a method in the QAbstractListModel derived MessageList which simply returns a QVariantMap

    P.S. Below is the new working version of the example app, in case anyone notices any misconceptions, please let me know

    MessageList.hpp:

    #ifndef MESSAGELIST_HPP #define MESSAGELIST_HPP #include "Message.hpp" #include <QObject> #include <QAbstractListModel> #include <QModelIndex> #include <QList> #include <QHash> #include <QVariant> #include <QMap> #include <QSharedPointer> class MessageList : public QAbstractListModel { Q_OBJECT public: typedef QSharedPointer<Message> MessagePointer; typedef QList<MessagePointer> MessagePointerList; typedef QMap<QString, MessagePointer> IndexMap; enum Roles { IdentifierRole, TitleRole, MessageRole, }; protected: MessagePointerList _list; IndexMap _indexMap; public: MessageList(); int rowCount(const QModelIndex& parent) const; QHash<int, QByteArray> roleNames() const; QVariant data(const QModelIndex& index, int role) const; bool insert( const QList<Message>& messages, int position = 0 ); bool reset(); Q_INVOKABLE QVariantMap get(const QString& identifier) const; const Message& at(int index) const; }; #endif // MESSAGELIST_HPP

    MessageList.cpp:

    #include "MessageList.hpp" #include <QObject> #include <QModelIndex> #include <QVariant> #include <QHash> #include <QByteArray> MessageList::MessageList() : QAbstractListModel(nullptr) { } int MessageList::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent) return _list.size(); } QHash<int, QByteArray> MessageList::roleNames() const { QHash<int, QByteArray> roles; roles[IdentifierRole] = "identifier"; roles[TitleRole] = "title"; roles[MessageRole] = "message"; return roles; } QVariant MessageList::data(const QModelIndex& index, int role) const { if(!index.isValid() || index.row() >= _list.size() || index.row() < 0 ) { return QVariant(); } switch(role) { case IdentifierRole: return _list.at(index.row())->identifier(); break; case TitleRole: return _list.at(index.row())->title(); break; case MessageRole: return _list.at(index.row())->message(); break; default: return QVariant(); } } bool MessageList::insert( const QList<Message>& messages, int position ) { beginInsertRows(QModelIndex(), position, position + messages.size() - 1); for(int row = 0; row < messages.size(); ++row) { IndexMap::const_iterator indexMapItr(_indexMap.constFind(messages.at(row).identifier())); if(indexMapItr == _indexMap.constEnd()) { MessagePointer newMessage(new Message(messages.at(row))); _list.insert(position, newMessage); _indexMap.insert(messages.at(row).identifier(), newMessage); } } endInsertRows(); return true; } bool MessageList::reset() { beginResetModel(); _list.clear(); __indexMap.clear(); endResetModel(); return true; } QVariantMap MessageList::get(const QString& identifier) const { QVariantMap result; IndexMap::const_iterator indexMapItr(_indexMap.constFind(identifier)); if(indexMapItr != _indexMap.constEnd()) { result["identifier"] = QVariant(indexMapItr->data()->identifier()); result["title"] = QVariant(indexMapItr->data()->title()); result["message"] = QVariant(indexMapItr->data()->message()); } return result; } const Message& MessageList::at(int index) const { return *(_list.at(index).data()); }

    main.cpp:

    #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "Message.hpp" #include "MessageList.hpp" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); MessageList messageList; messageList.insert(QList<Message> { Message("a", "first message", "this is a sample text message of the first message"), Message("b", "second message", "another sample text message of the second message"), Message("c", "third message", "yet a third text message sample"), Message("d", "fouth message", "last sample message") }); QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("MessageList", &messageList); engine.load(QUrl(QLatin1String("qrc:/main.qml"))); return app.exec(); }

    main.qml:

    import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Messages") Rectangle { id: menu color: Qt.rgba(0.9, 0.9, 0.9, 1) height: 32 anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right Text { anchors.left: parent.left anchors.margins: 8 anchors.verticalCenter: parent.verticalCenter text: "at id 'b' there is: " + MessageList.get("b").title } } ListView { model: MessageList anchors.top: menu.bottom anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom clip: true delegate: Rectangle { height: 32 Column { anchors.fill: parent anchors.margins: 8 spacing: 2 Text { text: title + " (" + identifier + ")" font.bold: true } Text { text: message } } } } }
  • 0 Votes
    3 Posts
    4k Views
    romsharkovR

    @SGaist returning a pointer in the getter and defining the Q_PROPERTY as a pointer to the list worked out fine! Thanks for that!

  • 0 Votes
    11 Posts
    4k Views
    R

    @SGaist OS X 10.10 and Win 10

  • 0 Votes
    10 Posts
    6k Views
    GrecKoG

    When no roles are passed as a parameter, all roles ares assumed to be changed.

    The most likely error of OP is to not call begin/endInsertRows (or modelReset is all the model is changed)

  • 1 Votes
    6 Posts
    6k Views
    p3c0P

    @KiNgFrUiT You're Welcome :) Thanks for sharing the complete solution. Also it would be better if you mark the post as solved so that others may know that the post has a solution.

  • 0 Votes
    2 Posts
    2k Views
    E

    From the QT documentation it seem to be possible : Exposing Attributes of C++ Types to QML

    Any data that is transferred from C++ to QML, whether as a property value, a method parameter or return value, or a signal parameter value, must be of a type that is supported by the QML engine.

    So why it is not working ? Is any of you succeed returning one or more object through method parameters ?

  • 0 Votes
    3 Posts
    2k Views
    V

    Hi

    try to use Binding to your CheckBox:

    Binding { target: checkbox property: 'checked' value: checkboxenable }

    where checkboxenable is role in your model

  • 0 Votes
    2 Posts
    2k Views
    p3c0P

    @JDGXNV
    The delegates are recycled every-time you scroll which means there are created and destroyed as and when required internally (More here: delegate). Caching them disables it. So I guess the problem should be on the delegate side i.e the delegate is trying to access some property which it is not able and hence crashes.

  • 0 Votes
    10 Posts
    26k Views
    A

    @SiliconKiwi helps, thanks.

  • 0 Votes
    5 Posts
    9k Views
    J

    @clogwog As expected

  • 0 Votes
    9 Posts
    4k Views
    S

    Finally I gave a shot to https://qt.gitorious.org/qt-labs/qml-object-model
    It works fine, just needed to reimplement setRoleNames (deprecated in qt5)
    Thanks again to the community :D