Size: a a a

2021 January 05

DK

Denis K in Qt
Михаил Серебренников
У QML достаточно простой и нестрогий синтаксис, и это развращает и приводит к говнокоду. Поэтому важно соблюдать соглашение о стиле кода. Я придерживаюсь следующим правилам.

Очерёдность при описании элемента
1. id (если нужен);
2. объявление новых property и signal;
3. установка значений существующих property:
   3.1 text, source, sourceComponent (как самые главные свойства);
   3.2 все остальные свойства;
   3.3 x,y,width,height,anchors;
   3.4 Behavior
4. QML-элементы (наследники Item и QtObjects);
5. states и transitions;
5. слоты и обработка сигналов (onClicked, Connections), но кроме Component.onCompleted и Component.onDestruction;
6. функции;
7. Component.onCompleted и Component.onDestruction.

Обработка создания и разрушения элемента (пункт 7) перенесена в конец, т.к. это очень важный и часто используемый кусок кода. Вставляю пробельные строки между элементами, id, блоком свойств и т.д.
Если блочные свойства (anchors, fonts и др.) содержат больше двух строк, то описываю через фигурные скобки. Оформление тернарного оператора - дело вкуса, но я стараюсь разбивать на три строки.

Файловая структура
Fonts/
   SomeFont.ttf
   Fonts.qrc
Images/
   SomeImage.svg
   Images.qrc
QML/
   Components/
       SomeComponent.qml
       qmldir
   JavaScript/
       SomeJsTool.js
   Pages/
       Page1/
           ComponentForPage1.qml
           qmldir
       Page1.qml
       Page2.qml
       qmldir
   Main.qml
   Consts.qml
   Colors.qml
   qmldir
   Qml.qrc
Translations/
   Project_ru_RU.ts
   Project_ru_RU.qm
   Translations.qrc

По требованию Qt qml-файлы должны начинаться с заглавной буквы. Поэтому для единообразия я остальные файлы и каталоги (кроме qmldir) также задаю в CamelCase. Но это дело вкуса. Также важно, чтобы название файла и id в его описании совпадал.

Модули и import
Свои QML-файлы можно оформлять в виде модулей через qmldir. Также можно просто в import писать относительный путь (import "../../Components") до нужно каталога или абсолютный путь (import "qrc:/Components"). Моя практика показала, что если не писать библиотеку для сторонних людей, то лучше не использовать qml-модули. Т.к. и без них всё работает без конфликтов, и при этом не тратиться куча времени на дублировании имени файла в qmldir.

С++ и QML
Тут всё просто. В C++ должно быть вынесено максимум бизнес-логики. А её выполнение не должно блокировать GUI-поток.
в закладки! спасибо)
источник

КГ

Константин Громов... in Qt
Stas Koynov
какой коннект ты о чем?
ты создал ПОток. в этом потоке будет выполняться твоя (переданная) функция. в нее будут переданы аргументы, если ты их передал. Поток нужно будет потом стартануть при помощи метода старт
Можно аналогичным образом создать поток, создать функцию и соединить их.. Ещё использовать moveRoThread и также start..
источник

SK

Stas Koynov in Qt
Константин Громов
Можно аналогичным образом создать поток, создать функцию и соединить их.. Ещё использовать moveRoThread и также start..
ты не можешь переместить функцию в поток. ты перемещаешь туда КОбжект-ы. чтобы потом если нужно, обрабатывать их слоты в этом потоке. для этого в нем должна быть запущена очередь обработки exec начиная там с какой-то версии метод потока run запускает ее по умолчанию
источник

JS

Jerzy Syrowiecki in Qt
Nastya Medveda
Добрый вечер, Я хочу поменять иконку в ячейке   QTableView/QAbstractTableModel.

Скажите, пожалуйста, как  обновить QDecorationRole  не меняя содержимое  таблицы?
В документации вQAbstractTableModel  нашла только insert/remove, но не update.
в стандартной модели есть готовые иконки у элементов. если стандартная модель не подходит, я бы попробовал скопировать из неё кусок кода, отвечающий за иконку
источник

AS

Anatoly Shirokov in Qt
Nastya Medveda
Добрый вечер, Я хочу поменять иконку в ячейке   QTableView/QAbstractTableModel.

Скажите, пожалуйста, как  обновить QDecorationRole  не меняя содержимое  таблицы?
В документации вQAbstractTableModel  нашла только insert/remove, но не update.
Ты в модели должна обработать в data() роль DecorateRole, все верно, и вернуть для нее иконку
источник

AS

Anatoly Shirokov in Qt
источник

AS

Anatoly Shirokov in Qt
Все, теперь праздник-праздник :)))
источник

NM

Nastya Medveda in Qt
Anatoly Shirokov
Ты в модели должна обработать в data() роль DecorateRole, все верно, и вернуть для нее иконку
Сппасибо. Я так и делаю, но я не могу вызывать layoutchanged, так как у меня ProxyModel. ПОтмоу я ищу альтернативный вариант.
источник

AS

Anatoly Shirokov in Qt
Nastya Medveda
Сппасибо. Я так и делаю, но я не могу вызывать layoutchanged, так как у меня ProxyModel. ПОтмоу я ищу альтернативный вариант.
emit dataChanged
источник

AS

Anatoly Shirokov in Qt
Nastya Medveda
Сппасибо. Я так и делаю, но я не могу вызывать layoutchanged, так как у меня ProxyModel. ПОтмоу я ищу альтернативный вариант.
для чего тебе layoutChanged? задачу опиши
источник

NM

Nastya Medveda in Qt
Anatoly Shirokov
для чего тебе layoutChanged? задачу опиши
у меня есть таблица, которая отображает файлы. также у меня есть Action скачивания файла. Я хочу чтоб когда файл скачался, то в таблице появлялась галочка в строке с этим файлом.
источник

AS

Anatoly Shirokov in Qt
Nastya Medveda
у меня есть таблица, которая отображает файлы. также у меня есть Action скачивания файла. Я хочу чтоб когда файл скачался, то в таблице появлялась галочка в строке с этим файлом.
тогда emit dataChanged будет достаточно. предположим, что у тебя в модели есть поле "downloaded", если оно true, то ты выводишь иконку:
QVariant MyTableModel::data(const QModelIndex& index, int role) const
{
   if (index.isValid()) {
       switch (role) {
       case Qt::DisplayRole:
           ...
       case Qt::DecorationRole:
           if( m_data[index.row()].downloaded ) {
               QIcon icon("://downloaded.png");
               return icon;
           }
       }
   }
   return QVariant();
}
источник

AS

Anatoly Shirokov in Qt
когда данные скачаны заведи в модели установку этого флага:
void MyTableModel::setDownloaded(int row, bool downloaded) {
    if( m_data[row].downloaded != downloaded ) {
          m_data[row].downloaded = downloaded;
          emit dataChanged(index(row, 0), index(row, columnCount()), QVector<int>() << Qt::DecorationRole);
    }
}
источник

NM

Nastya Medveda in Qt
Anatoly Shirokov
тогда emit dataChanged будет достаточно. предположим, что у тебя в модели есть поле "downloaded", если оно true, то ты выводишь иконку:
QVariant MyTableModel::data(const QModelIndex& index, int role) const
{
   if (index.isValid()) {
       switch (role) {
       case Qt::DisplayRole:
           ...
       case Qt::DecorationRole:
           if( m_data[index.row()].downloaded ) {
               QIcon icon("://downloaded.png");
               return icon;
           }
       }
   }
   return QVariant();
}
Да, с обычной моделью это работает. Проблема в том, что у меня к этой модели еще привязана  ProxyModel, которая не обновляется при QabstractTableModel.layoutChanged.emit().
На стековерфлоу есть такая проблема и там предлагается использовать BeginInsertROws вместо layoutChanged
источник

NM

Nastya Medveda in Qt
собственно я использую именно InsertRows/DElete Rows/ResertModel при работе с данными.
источник

NM

Nastya Medveda in Qt
Спасибо за помощь, я сейчас делаю именно как ты и написал.
источник

AS

Anatoly Shirokov in Qt
Nastya Medveda
Спасибо за помощь, я сейчас делаю именно как ты и написал.
я проверил, emit dataChanged не рефрешит содержимое TableView и это довольно странно.
источник

NM

Nastya Medveda in Qt
Anatoly Shirokov
я проверил, emit dataChanged не рефрешит содержимое TableView и это довольно странно.
Это работает пока нет Proxy. Если есть прокси, то при изменении данных layoutChanged вызывает ошибку обращения к несуществующим индексам в  Proxy
источник

AS

Anatoly Shirokov in Qt
Nastya Medveda
Это работает пока нет Proxy. Если есть прокси, то при изменении данных layoutChanged вызывает ошибку обращения к несуществующим индексам в  Proxy
У меня ошибки нет, но и не рефрешит.
источник

AS

Anatoly Shirokov in Qt
У меня сохранился тот пример с прокси
источник