Отредактируйте QStandardItemModel через TableView с помощью настраиваемого делегата

numberCruncher

У меня есть QStandardItemModel, который я отображаю в виде таблицы QML.

Вот модель:

class mystandardmodel: public QStandardItemModel
{

public:
    mystandardmodel();
    enum Role {
         role1=Qt::UserRole,
         role2
     };

     explicit mystandardmodel(QObject * parent = 0): QStandardItemModel(parent){}
     //explicit mystandardmodel( int rows, int columns, QObject * parent = 0 )
     //    : QStandardItemModel(rows, columns, parent){}

     QHash<int, QByteArray> roleNames() const{
          QHash<int, QByteArray> roles;
          roles[role1] = "one";
          roles[role2] = "two";
          return roles;
 }
};

и вот как модель отображается с использованием пользовательских делегатов:

    TableView {
        id: tableView2
        x: 69
        y: 316
        width: 318
        height: 150
        TableViewColumn {
            title: "Parameter Name"
            role: "one"
        }
        TableViewColumn {
            title: "Value"
            role: "two"
            delegate: myDelegate
        }
        model: myTestModel
    }

    Component {
        id: myDelegate
        Loader {
            property var roleTwo: model.two
            sourceComponent: if(typeof(roleTwo)=='boolean') {
                                 checkBoxDelegate}
                             else { stringDelegate}
        }
    }

    Component {
        id: checkBoxDelegate
        CheckBox{text: roleTwo}
    }

    Component {
        id: stringDelegate
        TextEdit {text: roleTwo}
    }

Я заполнил модель следующим образом:

 mystandardmodel* mysmodel=new mystandardmodel(0);
 QStandardItem* it = new QStandardItem();
 it->setData("data1", mystandardmodel::role1);
 it->setData(true, mystandardmodel::role2);
 it->setCheckable(true);
 it->setEditable(true);
 mysmodel->appendRow(it);
 QStandardItem* it2 = new QStandardItem();
 it2->setData("data2",mystandardmodel::role1);
 it2->setData("teststring",mystandardmodel::role2);
 mysmodel->appendRow(it2);

Как сделать модель редактируемой, чтобы с помощью флажка или редактирования текст передавался обратно в модель?

Изменить: я попытался следовать предложению в QML TableView, когда щелкнул, отредактировал данные (например, excel) и использовал модель набора:

Component {
    id: myDelegate
    Loader {
        property var roleTwo: model.two
        property int thisIndex: model.index
        sourceComponent: if(typeof(roleTwo)=='boolean') {
                             checkBoxDelegate}
                         else { stringDelegate}
    }
}

Component {
    id: checkBoxDelegate
    CheckBox{text: roleTwo
        onCheckedChanged: {
            myTestModel.setData(0,"two",false)
            console.log('called',thisIndex)
        }
    }

}

Component {
    id: stringDelegate
    TextEdit {text: roleTwo
        onEditingFinished: {
            myTestModel.setData(thisIndex,"two",text)
           console.log('called',thisIndex)
        }
    }
}

Индекс в порядке, но кажется, что он не действует (я добавил второй TableView с той же моделью, но данные там не обновляются, если я редактирую их в первом TableView)

Eyllanesc

Использование setData()может быть вариантом, но для этого требуется целочисленное значение, указывающее на роль, которая недоступна в QML или, скорее, не является элегантной.

Лучше создать новую, которая есть Q_INVOKABLE. Поскольку обновление отображается в представлении, нет необходимости уведомлять его, кроме как вызвать странные события.

для получения строки мы используем геометрию и rowAt()метод TableView.

Ниже приведен пример:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStandardItemModel>

class MyStandardModel: public QStandardItemModel
{
    Q_OBJECT
public:
    enum Role {
        role1=Qt::UserRole+1,
        role2
    };

    using QStandardItemModel::QStandardItemModel;

    QHash<int, QByteArray> roleNames() const{
        QHash<int, QByteArray> roles;
        roles[role1] = "one";
        roles[role2] = "two";
        return roles;
    }

    Q_INVOKABLE void updateValue(int row, QVariant value, const QString &roleName){

        int role = roleNames().key(roleName.toUtf8());
        QStandardItem *it = item(row);
        if(it){
            blockSignals(true);
            it->setData(value, role);
            Q_ASSERT(it->data(role)==value);
            blockSignals(false);
        }

    }
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    MyStandardModel model;

    for(int i=0; i< 10; i++){
        auto item = new QStandardItem;
        item->setData(QString("data1 %1").arg(i), MyStandardModel::role1);
        if(i%2 == 0)
            item->setData(true, MyStandardModel::role2);
        else {
            item->setData(QString("data2 %1").arg(i), MyStandardModel::role2);
        }
        model.appendRow(item);
    }
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("myTestModel", &model);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

#include "main.moc"

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    TableView {
        id: tableView2
        anchors.fill: parent
        TableViewColumn {
            title: "Parameter Name"
            role: "one"
        }
        TableViewColumn {
            title: "Value"
            role: "two"
            delegate: myDelegate
        }
        model: myTestModel
    }

    Component {
        id: myDelegate
        Loader {
            property var roleTwo: model.two
            sourceComponent: typeof(roleTwo)=='boolean'? checkBoxDelegate: stringDelegate
        }
    }

    Component {
        id: checkBoxDelegate
        CheckBox{
            checked: roleTwo
            onCheckedChanged:{
                var pos = mapToGlobal(0, 0)
                var p = tableView2.mapFromGlobal(pos.x, pos.y)
                var row = tableView2.rowAt(p.x, p.y)
                if(row >= 0)
                    myTestModel.updateValue(tableView2.row, checked, "two")
            }
        }
    }

    Component {
        id: stringDelegate
        TextField {
            text: roleTwo
            onEditingFinished: {
                var pos = mapToGlobal(0, 0)
                var p = tableView2.mapFromGlobal(pos.x, pos.y)
                var row = tableView2.rowAt(p.x, p.y)
                if(row >= 0)
                    myTestModel.updateValue(tableView2.row, text, "two")
            }

        }
    }
}

Полный пример можно найти по следующей ссылке .

Эта статья взята из Интернета, укажите источник при перепечатке.

Если есть какие-либо нарушения, пожалуйста, свяжитесь с[email protected] Удалить.

Отредактировано в
0

я говорю два предложения

0обзор
Войти в системуУчаствуйте в комментариях

Статьи по теме

TOP список

  1. 1

    Распределение Рэлея Curve_fit на Python

  2. 2

    TypeError: store.getState não é uma função. (Em 'store.getState ()', 'store.getState' é indefinido, como posso resolver esse problema?

  3. 3

    В типе Observable <unknown> отсутствуют следующие свойства из типа Promise <any>.

  4. 4

    Как добавить Swagger в веб-API с поддержкой OData, работающий на ASP.NET Core 3.1

  5. 5

    How to click an array of links in puppeteer?

  6. 6

    Merging legends in plotly subplot

  7. 7

    ViewPager2 мигает / перезагружается при смахивании

  8. 8

    Отчеты Fabric Debug Craslytic: регистрация, отсутствует идентификатор сборки, применить плагин: io.fabric

  9. 9

    How to normalize different curves drawn with geom = "step" when using stat_summary

  10. 10

    无法通过Vue在传单中加载pixiOverlay

  11. 11

    как я могу удалить vue cli 2?

  12. 12

    Как я могу нарисовать заполненный прямоугольник в JFreeChart?

  13. 13

    SQL Вычтите две строки друг от друга в одном столбце, чтобы получить результат

  14. 14

    Elasticsearch - Нечеткий поиск не дает предложения

  15. 15

    Single legend for Plotly subplot for line plots created from two data frames in R

  16. 16

    Описание моего типа Parser как серии преобразователей монад

  17. 17

    Как изменить цвета запятых и скобок в VS Code

  18. 18

    Сброс значения <input type = "time"> в Firefox

  19. 19

    Почему прокси в vue.config.js 404

  20. 20

    Как установить параметр -noverify с gradle ktx для робоэлектрических тестов Android?

  21. 21

    В чем разница между ifstream, ofstream и fstream?

популярныйтег

файл