alex_lip
Oct. 31, 2018, 6:08 p.m.

Динамическая подмена моделей для ListView

Есть ListView для которого я меняю модели, которые заполняю из SqlLite. В принципе все работает, но кое-что непонятно.

Пример - при клике на текущей строке ListView у меня срабатывает следующая функция


  1. MouseArea {
    onClicked: { EsdDb.readDataSea_phones(parent_officeid);}
    }

где

  1. function readDataSea_phones(m_usersid) {
  2. seaPhones.clear();
  3.  
  4. if(!db) { return; }
  5.  
  6. db.transaction( function(tx) {
  7. var sql_text1='select surname, name, middle_name, name_rec, usersid, staffid, name_sokr, officeid, av_path from all_tel where usersid = '+'\'' +m_usersid +'\'';
  8.  
  9. var result = tx.executeSql(sql_text1);
  10. for(var i = 0; i < 1; i++) {
  11. seaPhones.append({phone:result.rows.item(i).surname+" "+ result.rows.item(i).name+" "+result.rows.item(i).middle_name, tip_n:"" ,usersid: result.rows.item(i).usersid, av_path: result.rows.item(i).av_path});
  12. }
  13. } );
  14.  
  15. db.transaction( function(tx) {
  16. var sql_text='select phone, tip_n, usersid from all_phones where usersid = '+'\'' +m_usersid +'\'';
  17. var result = tx.executeSql(sql_text);
  18. for(var i = 0; i < result.rows.length; i++) {
  19. seaPhones.append({phone:result.rows.item(i).phone, tip_n: result.rows.item(i).tip_n, usersid: result.rows.item(i).usersid, av_path: ""});
  20. }
  21. } );
  22. root_i.model_name="seaPhones";
  23. view_all_tree.model=seaPhones;
  24.  
  25. }



В этом скрипте я выполняю запрос к базе данных и подменяю текущую модель для ListView на другую. Все работает. Но я в консоле вижу, что QML сначала рефрешит старую модель, а уже затем отображает новую. У меня генерятся ошибки вывода на экран типа qrc:/content/TelSpr.qml:759 : ReferenceError: phone is not defined , и действительно - поле phone у меня описано в той модели, которую я присваиваю в скрипте, А не в той которая текущая была. Но скрипт то отработал. Я вижу по логам, что скрипт отработал, потом ошибки предыдущего отображения, потом нормальный вывод на экран той модели, которую я заполнил в скрипте.


данные модели я вывожу так


  1. Text {
  2. id:text_tree
  3. padding : 5
  4. width: parent.width
  5. renderType: Text.NativeRendering
  6. font.pixelSize: dp(19);
  7. font.bold: true
  8. textFormat: Text.StyledText
  9. wrapMode: "Wrap"
  10.  
  11. function model_field(field)
  12. {
  13. if(field ==='myModel_All_tree'){
  14. return name_office
  15. }
  16. if(field ==='myModel_All_tel'){
  17. return fio
  18. }
  19. if(field ==='myModel_All_phones'){
  20. return phone
  21. }
  22. if(field ==='seaModel_id'){
  23. return name_sokr+" "+name_rec
  24. }
  25. if(field ==='seaModel'){
  26. return name_sokr+" "+name_rec
  27. }
  28. if(field ==='seaPhones'){
  29. return phone+" "+tip_n
  30. }
  31. if(field ==='seaTree'||field ==='seaTree_lvl_1'||field ==='seaTree_lvl_2'||field ==='seaTree_lvl_3'){
  32. return name_office
  33. }
  34. else
  35. {
  36. return ""
  37. }
  38. }
  39. text: model_field(root_i.model_name)
  40. }
  41. }



То есть в зависимости от того какая модель - выводятся соотв. поля. Еще раз повторюсь - на вид все работает. Но мне не нравится то что происходит в логах.











3

Do you like it? Share on social networks!

4
Evgenii Legotckoi
  • Oct. 31, 2018, 7 p.m.

Думаю, что проблема вот в этом.

root_i.model_name="seaPhones";

view_all_tree.model=seaPhones;

Вернее в местоположении этих строчек.

Сначала установите имя модели, а потом уже данные с полем phone начинайте добавлять. Скорее всего перерисовка выпонляется при каждом добавлении данных в таблицу, то есть при каждом append .

А вообще, не хорошо в представлении писать невалидные поля. Благо, что это JavaScript.




    alex_lip
    • Oct. 31, 2018, 7:08 p.m.
    • (edited)

    пробовал. В этом случае сначала идет рефреш старой модели, потом скрипт, потом отображение новой. Но ошибки из-за рефреша все равно идут. 

    То есть похоже рефреш происходит в момент выполнения функции view_all_tree.model=seaPhones;


    В принципе я могу все модели привести к набору одинаковых полей. Тогда ошибок не будет. Но почему происходит рефреш ListView с привязкой к старой модели, когда там уже новые данные. Вот вопрос

      Evgenii Legotckoi
      • Oct. 31, 2018, 7:26 p.m.

      Я бы ещё попробовал написать или два разных представления, или два разных делегате, и менял бы делегаты в зависимости от устанавливаемой модели.

        alex_lip
        • Nov. 1, 2018, 12:48 p.m.
        • The answer was marked as a solution.

        В делегатах слишком много кода. Я просто понаписал фиктивных полей в моделей - чтобы не было ошибок. И все оставил как есть.

          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