Skip to content
  • 0 Votes
    6 Posts
    5k Views
    Y

    @michalos I'm not sure if I can help you but seems like model test code works for me.

    What I did:

    Added modeltest.h and cpp into my project Added "testlib" into "QT" section of project file Added this to modeltest.h: #include <QtTest/qtestcase.h> #define qVariantCanConvert(_type_, _var_) _var_.canConvert(QMetaType::_type_) Changed expressions like "qVariantCanConvert<QString> ( variant)" to "qVariantCanConvert(QString, variant)" in modeltest.h

    And... my sample model failed to pass the test of course :D

  • 0 Votes
    4 Posts
    3k Views
    p3c0P

    @tamlong0205 I think most of this can be done from C++ side.

    You can add a function in the model which can return what type is the data for current index. This function will be called from QML and depending upon its value use a Loader to load the specific delegate.

    Perhaps setting currentIndex in Component.onCompleted handler ?

    Create a C++ function which will store in info in the model itself i.e When you change the index in ComboBox call this function and update the value there and may be maintain a role to store this update.

  • 0 Votes
    1 Posts
    660 Views
    No one has replied
  • 0 Votes
    21 Posts
    7k Views
    kshegunovK

    @Guy-Gizmo said:

    The whole point of me setting it up that way is that the actual logical structure of the data and the physical arrangement and implementation of it are conceptually completely separate. The latter is abstracted away by the interface of the former.

    Then I think the cleanest solution is to have a tree (or w/e) that represents your logical structure, and that will abstract the whole physical layer. For a simple example you can look at the docs - the simple tree model.
    You can put anything in that tree and it's basically your "data interface". It also shouldn't care that the physical nodes are destroyed as long as there's a logical node living. This way you don't have with model indexes and things getting destroyed in the background, because it's the middleman's responsibility. You should hover take care to notify the model when a node/leaf from the "logical structure" tree is destroyed (through the appropriate signals), so views can make proper adjustments.

    I hope that helps somewhat.

    Kind regards.

  • 0 Votes
    2 Posts
    917 Views
    Guy GizmoG

    Someone on stackoverflow was kind enough to point out my error. My parent method() should have been:

    QModelIndex MyModel::parent(const QModelIndex &index) const { if (!index.isValid()) { return QModelIndex(); } QObject *item = (QObject *)index.internalPointer(); Directory *parentItem = qobject_cast<Directory *>(item->parent()); if (!parentItem || parentItem == invisibleTopLevelDirectory()) { return QModelIndex(); } Directory *parentOfParentItem = qobject_cast<Directory *>(parentItem->parent()); if (!parentOfParentItem) { return QModelIndex(); } int listIndex = parentOfParentItem->indexOfItem(parentItem); if (listIndex < 0) { return QModelIndex(); } else { return createIndex(listIndex, index.column(), parentItem); } }
  • 0 Votes
    9 Posts
    9k Views
    TrilecT

    Cool, Thanks for all the insite: I have solved the problem with a little more testing.
    For the sake of completeness and for others Ive included my code:

    void DialogStructureXML::on_btn_add_toroot_released() { QModelIndex currentIndex = ui->tree->selectionModel()->currentIndex(); QModelIndex rootIndex = ui->tree->rootIndex(); QModelIndex traceIndex = currentIndex; QModelIndex child = currentIndex; tree_model *model = (tree_model*) ui->tree->model(); int rowCount = model->rowCount(); int currentRow = 0; int prevRow = 0; //some string cleanup QString ItemText = ui->edit_textvaluefortree->text() ; ItemText.simplified(); //If its a valid index (ie: valid something in the GUI tree) trace back to the parent if ( traceIndex.isValid() ) { while ( traceIndex.isValid() ) { currentRow = traceIndex.row()+1; traceIndex = model->parent(traceIndex); } } if (!model->insertRow(currentRow, rootIndex)) return; child = model->index(currentRow, 0, rootIndex); //Column index 0 model->setData(child, QVariant( ItemText ), Qt::EditRole); return; }
  • 0 Votes
    1 Posts
    1k Views
    No one has replied
  • 0 Votes
    3 Posts
    3k Views
    N

    @SGaist Thanks for your advise, it works like well now.

  • 0 Votes
    4 Posts
    3k Views
    p3c0P

    @sigmaN AFAIK there is no ready-made method for it. You can try digging up the source and particularly the delegate part of it only in which these roles are available.
    Apart from that there is another way to access the data. Iterating through the children of ListView's contentItem as all the items (delegate too) declared inside ListView are parented to it. But IMO it is not a recommended way.

  • 1 Votes
    10 Posts
    3k Views
    kshegunovK

    @Michael-Scopchanov said in QComboBox with QAbstractItemModel, default text problem:

    "I would be glad to" is considered a polite form of speech.

    Provide some minimal example or code if you expect someone to look at it, comment and try to help you. This kind of arguing does not, nor is going to, get you anywhere.

    PS. Notice I didn't use "please", "would you", "be so kind as to" etc., because these words have no meaning in a technical discussion. We want facts and well structured problems to take a stab at and have some fun, and you want answers; it's a symbiosis and we don't get paid for our time. So unless someone's been openly hostile or have shown malice, which nobody had, then just as a friendly advice you'd do yourself good to grow some thicker skin.

  • 0 Votes
    5 Posts
    5k Views
    Joel BodenmannJ

    @Chris-Kawa Oh, now i understand. Well, this makes a lot of sense.

    Thank you for your help, very appreciated!

  • 0 Votes
    2 Posts
    2k Views
    SGaistS

    Hi,

    There's no ready made code to dump your model since only you know what make sense to dump. So yes you'll have to write the dumper and loader yourself. QDataStream comes to mind for that task.

    Hope it helps

  • 0 Votes
    21 Posts
    9k Views
    Joel BodenmannJ

    In order to be future-proof I implemented the abstract node based concept as suggested by @Chris-Kawa and @Harb (in the first post).
    Everything is working nicely.

    Thanks for your help!

  • 0 Votes
    2 Posts
    2k Views
    V

    Here's the code

    class TreeModel : public QAbstractItemModel { Q_OBJECT public: explicit TreeModel(const QString &data, QObject *parent = 0); ~TreeModel(); enum TreeRoles { TitleRole = Qt::UserRole + 1, SummaryRole }; QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; bool setData(const QModelIndex &index, const QVariant &value, int role); Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE; int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; protected: QHash<int, QByteArray> roleNames() const; private: TreeItem *rootItem; };

    here's the code of the TreeView

    TreeView { id: view anchors.fill: parent anchors.margins: 2 * 12 + row.height model: treeModel selection: selectionModel headerVisible: false itemDelegate: Component { id: dragDelegate MouseArea { id: dragArea property bool held: false height: content.height drag.target: held ? content : undefined drag.axis: Drag.YAxis onPressAndHold: held = true onReleased: held = false Rectangle { id: content anchors { horizontalCenter: parent.horizontalCenter verticalCenter: parent.verticalCenter } width: dragArea.width height: 20 Text{ anchors.verticalCenter: parent.verticalCenter text: styleData.value } border.width: 1 border.color: "lightsteelblue" color: dragArea.held ? "lightsteelblue" : "green" Behavior on color { ColorAnimation { duration: 100 } } radius: 2 states: State { when: dragArea.held ParentChange { target: content; parent: root } AnchorChanges { target: content anchors { horizontalCenter: undefined; verticalCenter: undefined } } } } } } TableViewColumn { title: "Name" role: "Title" resizable: true } onClicked: { console.log("clicked", index) } onDoubleClicked: { console.log("double clicked " + index) clickedIndex = index console.log("DoubleClickedIndex " + clickedIndex) textEditRect.visible = true; textEdit.text = fileSystemModel.data(index, "Title") textEditRect.forceActiveFocus() isExpanded(index) ? collapse(index) : expand(index) } }
  • 0 Votes
    2 Posts
    2k Views
    CharbyC

    Has any one experienced the same problem ? Any idea of a possible workaround ?
    Thanks for your help.

  • 0 Votes
    4 Posts
    7k Views
    R

    @t3685
    As stated in the OP, I know I can write specific getter/setter methods into my QAbstractItemModel subclasses.
    However, if that really was the only option then QML would be effectively useless for nontrivial data-driven applications as the data models cease to be a standard interface.

    @p3c0
    Thanks, I hadn't thought of doing it that way.
    In Qt 5.4 you can do this if you set Q_INVOKABLE on QAbstractItemModel::index(int row, int column, const QModelIndex &parent) and QAbstractItemModel::data(const QModelIndex &index, int role) methods.
    I'm guessing this has been done for you in Qt 5.5.

    I have also found that in Qt 5.4 (and presumably 5.5) it's also possible to get there via a DelegateModel (often called a VisualDataModel in the documentation), as the DelegateModelGroup within that has a get(row) function that returns an Object through which you can access the data in the same way as in a QML Delegate.
    http://doc.qt.io/qt-5.4/qml-qtqml-models-delegatemodelgroup.html#get-method
    However, I haven't yet figured out when it reads the data from the underlying model.

    Thus, if the DelegateModel has only the default DelegateModelGroup:

    myDelegateModel.items.get(%row%).model.%role_name%

    In this, myDelegateModel is a DelegateModel object (which may also be used as the model in a ListView, GridView or PathView), %row% is the row number and %role_name% is the role.
    Set myDelegateModel.rootIndex to the appropriate parent QModelIndex.

    PS: $Deity the documentation is beyond awful. So many links straight back to exactly where you are masquerading as a link to what the thing is.

  • 0 Votes
    1 Posts
    659 Views
    No one has replied
  • 0 Votes
    2 Posts
    1k Views
    Chris KawaC

    Something like this should do the trick:

    void MyDialog::accept() { stuff->setFocus(); //to move focus away from the table or any delegate if( /* do any data validation */) QDialog::accept(); //call base implementation only if everything is ok }