T
Jan. 25, 2021, 1:21 p.m.

AbstractListModel использование в нескольких элементах

Всем привет! Подскажите почему у меня крашится программа когда я использую мою абстрактную модель в повторяющихся элементах QML?
У меня есть 3 элемента (2 из них одинаковые) которые используют одну и ту же модель данных. Когда ко всем трём присвоена модель, программа крашится, иногда выдаёт std::bad_alloc. Крашится тока в дебаге, в релизе работает. Когда от одного из повторяющихся снимаю модель тогда работает.

2

Do you like it? Share on social networks!

8
Алексей Внуков
  • Jan. 25, 2021, 2:11 p.m.

без кода - годание на кофейной гуще.

    T
    • Jan. 25, 2021, 3:05 p.m.
    • (edited)

    Не знаю чем поможет код. Смымсл в том что есть listView Arm, на экране их 2, они должны отображать данные одной и той же модели. Но программа крашится когда присваеваешь модель обоимю

    1. // main
    2. qmlRegisterType<DriveModel>("TS.Drive", 1, 0, "DriveModel");
    3. qmlRegisterUncreatableType<Drives>("TS.Drive", 1, 0, "Drives", "");
    4. qmlRegisterUncreatableMetaObject(DriveModel::staticMetaObject, "TS.Drive", 1, 0, "Drive", "Error: only enums");
    5. context->setContextProperty("drives", &drives);
    1. // model
    2. class Drives;
    3. class DriveModel : public QAbstractListModel
    4. {
    5. Q_OBJECT
    6. Q_PROPERTY(Drives *list READ list WRITE setList)
    7.  
    8. public:
    9. explicit DriveModel(QObject *parent = nullptr) : QAbstractListModel(parent) , mList(nullptr){ }
    10. enum Role
    11. {
    12. TYPE = 0,
    13. CTRL = 1,
    14. MOTOR = 2,
    15. SENSOR = 3,
    16. MOTQTY = 4,
    17. };
    18. Q_ENUM(Role)
    19.  
    20.  
    21. int rowCount(const QModelIndex &parent = QModelIndex()) const override
    22. {
    23. if (parent.isValid() || !mList) return 0;
    24. return mList->size();
    25. }
    26.  
    27. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
    28. {
    29. if (!index.isValid() || !mList) return QVariant();
    30. const Drive &drive = mList->at(index.row());
    31. switch (role)
    32. {
    33. case TYPE:return QVariant(drive.type);
    34. case CTRL:return QVariant(drive.ctrl);
    35. case MOTOR:return QVariant(drive.motor);
    36. case SENSOR:return QVariant(drive.sensor);
    37. case MOTQTY:return QVariant(drive.motorQty);
    38. }
    39. return QVariant();
    40. }
    41.  
    42. virtual QHash<int, QByteArray> roleNames() const override
    43. {
    44. QHash<int, QByteArray> names;
    45. names[TYPE] = "type";
    46. names[CTRL] = "ctrl";
    47. names[MOTOR] = "motor";
    48. names[SENSOR] = "sensor";
    49. names[MOTQTY] = "motQty";
    50. return names;
    51. }
    52.  
    53. Drives *list() const
    54. {
    55. return mList;
    56. }
    57.  
    58. void setList(Drives *list)
    59. {
    60. beginResetModel();
    61. if (mList) mList->disconnect(this);
    62. mList = list;
    63.  
    64. if (mList) {
    65. connect(mList, &Drives::preItemAppended, this, [=]() {
    66. const int index = mList->size();
    67. beginInsertRows(QModelIndex(), index, index);
    68. });
    69. connect(mList, &Drives::postItemAppended, this, [=]() {
    70. endInsertRows();
    71. });
    72.  
    73. connect(mList, &Drives::preItemRemoved, this, [=](int index) {
    74. beginRemoveRows(QModelIndex(), index, index);
    75. });
    76. connect(mList, &Drives::postItemRemoved, this, [=]() {
    77. endRemoveRows();
    78. });
    79. connect(mList, &Drives::preResetting, this, [=]() {
    80. beginResetModel();
    81. });
    82. connect(mList, &Drives::postResetting, this, [=]() {
    83. endResetModel();
    84. });
    85. connect(mList, &Drives::dataChanged, this, [=](int index, int role) {
    86. QModelIndex i = createIndex(index, 0);
    87. emit dataChanged(i, i, QVector<int>() << role);
    88. });
    89. }
    90. endResetModel();
    91. }
    92.  
    93. private:
    94. Drives *mList;
    95. };
    1. DriveModel{
    2. id: drivesModel
    3. list: drives
    4. }
    5.  
    6. Item {
    7. height: 790
    8. width: 260
    9. ArmBackground{ id: leftArmBgrd; position: 1;}
    10. ColumnLayout{
    11. anchors.fill: parent
    12. StyleLabel{
    13. text: qsTr("ЛЕВЫЙ РЫЧАГ")
    14. Layout.alignment: Qt.AlignHCenter
    15. Layout.topMargin: 10
    16. color: leftArmColor;
    17. }
    18. Arm{ id: leftArm; position: 1;// model: drivesModel
    19. Layout.fillHeight: true; Layout.leftMargin: 5 }
    20. JoystickEmulator{
    21. id:armEmul
    22. width: parent.width - 80
    23. height: width
    24. Layout.leftMargin: 30
    25. onMoved: ctrl.onUpdateVirtualArm(xValue, yValue,
    26. armEmul1.xValue, armEmul1.yValue);
    27. }
    28. Item { height: 10;}
    29. }
    30. }
    31.  
    32. Item {
    33. height: 790
    34. width: 260
    35. ArmBackground{id: rightArmBgrd; position: 2}
    36. ColumnLayout{
    37. anchors.fill: parent
    38. StyleLabel{
    39. text: qsTr("ПРАВЫЙ РЫЧАГ")
    40. Layout.alignment: Qt.AlignHCenter
    41. Layout.topMargin: 10
    42. color: rightArmColor;
    43. }
    44. Arm{ id: rightArm; position: 2; model: drivesModel
    45. Layout.fillHeight: true; Layout.leftMargin: 25 }
    46. JoystickEmulator{
    47. id:armEmul1
    48. width: parent.width - 80
    49. height: width
    50. Layout.leftMargin: 50
    51. onMoved: ctrl.onUpdateVirtualArm(armEmul.xValue,
    52. armEmul.yValue, xValue, yValue);
    53. }
    54. Item { height: 10;}
    55. }
    56. }
    57.  

    QObject::~QObject: Timers cannot be stopped from another thread
    QML debugging is enabled. Only use this in a safe environment.
    terminate called after throwing an instance of 'std::bad_alloc'
    what(): std::bad_alloc

      T
      • Jan. 25, 2021, 3:19 p.m.

      Да и ещё есть третий элемент, он свёрстан подругому нежели эти, но тоже отображает эту модель. И вот он никак не влияет. Падает только когда 2 одинаковых элемента с одной моделью. Неужели под каждый отдельную модель делать?

        Алексей Внуков
        • Jan. 25, 2021, 4:44 p.m.
        • (edited)

        ну начнем с того что у вас не правильно организована работа с потоками, о чем говорит первое предупреждение.
        у вас так же где-то не правильно создается обьект, из-за чего выскакивает std::bad_alloc. что за элемент Arm? для примера у меня могут и 10 элементов одновременно в одном окне использовать одну и туже модель без ошибок.
        проблема где-то у вас в реализации

          T
          • Jan. 25, 2021, 6:42 p.m.
          • The answer was marked as a solution.

          Разобрался. Извиняюсь за беспокойство. Я просто не поставил "model." перед переменными. Делаю рефакторинг под abstractModel, раньше модель была в QML и как то прокатывала без этого. На железе уже пол года работает старая версия. С потоками и bad alloc пока не понятно, ведь до abstractModel проблем не было и сейчас нет как проставил model. везде.

            T
            • Jan. 29, 2021, 3:15 p.m.

            К сожалению проблема всплыла позже. Если у вас есть несколько QAbstractModel то важно чтоб в них не было одинаковых так называемых rolenames. У меня в разных моделях было "type", из за этого она всё время била по неинициализованной памяти и падала.

              Алексей Внуков
              • Jan. 29, 2021, 5:51 p.m.
              • (edited)

              разные модели могут иметь одинаковые rolenames, и это никак не влияет на их работу. самый тривиальный пример - это модели которые отображают данные из БД, у каждой второй таблици есть поле id или n, и везде будет корректно работать роль idRole или nRole. проблемы могут быть в неправильной реализации модели

                T
                • Feb. 5, 2021, 3:27 p.m.

                Не прав был. В общем 3 дня разбирался. В итоге отказался от абстрактной модели, так как посмотрел на количество вызовов data(), на модель из 50ти параметров это было очень много при даже 10ти элементах. И даже с моделью созданой в qml программа вылетала на отладке. Особенно сразу падала при быстрой перемотке ListView. Создал 3 отдельные модели, тока при таких условиях не падает.

                  Comments

                  Only authorized users can post comments.
                  Please, Log in or Sign up
                  • Last comments
                  • AK
                    April 1, 2025, 11:41 a.m.
                    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
                  • Evgenii Legotckoi
                    March 9, 2025, 9:02 p.m.
                    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
                  • VP
                    March 9, 2025, 4:14 p.m.
                    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
                  • ИМ
                    Nov. 22, 2024, 9:51 p.m.
                    Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                  • Evgenii Legotckoi
                    Oct. 31, 2024, 11:37 p.m.
                    Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup