crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> QDataMaper и Битовые поля в CheckBox, Мапинг битовых полей из short в БД
JohnZ
  опции профиля:
сообщение 8.4.2021, 17:00
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 139
Регистрация: 19.7.2014
Пользователь №: 4190

Спасибо сказали: 10 раз(а)




Репутация:   0  


Всем Здравия !

Прошу прощения если не в том разделе спрашиваю, не знаю к какому разделу мой вопрос отнести.

Проблема следующая. На данный момент, если на форме н-ное количество битовых полей, которые в БД упакованы в один short/int, то приходится делать следующее:

1. Ложим на эту форму скрытый QSpinBox, который хранит полное значение short/int и связывается с полем БД QDataMaper-ом.

2. Так-же на форме ес-сно присутствуют QCheckBox-ы в н-ном количестве, и ес-сно с разными именами, что-бы их потом можно было отличить из скрипта.

3. При открытии или закрытии формы, соответствующие функции скрипта распаковывают / упаковывают значения из QCheckBox-ов
в значение в QSpinBox-е.

Каждый контрол на форме имеет свой уникальный Idd (динамические св-ва в QT-дизайнере) , по которому он и мапится в БД.
Ес-сно QCheckBox своего Idd не имеет, (на картинке показан для примера), за исключением случая если он один соответствует
одному полю short/int в БД.

Дык вотЪ, хотелось-бы добавить на форме QCheckBox-у доп. динамическое св-во Bit (см. в прицепе. Скрытый QSpinBox справа
в строке битовых полей) и обойтись БЕЗ вызова СКРИПТОВЫХ функций, и соотв-но без НЕОБХОДИМОСТИ их написания для форм
с упакованными битовыми полями. Any ideas ?

Если нужны куски исходников - выложу, но думаю и так понятно ...

Помогите plz кто сталкивался или в курсе. Может уже где-то решалось что-то подобное ?!

QT 4.8.6

Удачи !

Сообщение отредактировал JohnZ - 8.4.2021, 17:16
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 9.4.2021, 7:41
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2928
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


JohnZ, насколько мне помнится, это нужно что-то мутить с отдельной утилитой - дизайнером, потом делать плагин, гемор один ))

Если устроит вариант, могу предложить: в поле tooltip пиши json, а в конструкторе элемента пропарси.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
JohnZ
  опции профиля:
сообщение 9.4.2021, 13:48
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 139
Регистрация: 19.7.2014
Пользователь №: 4190

Спасибо сказали: 10 раз(а)




Репутация:   0  


Алексей, Дизайнер ты подразумеваешь родной QT-шный тот что в посте выше, или Конфигуратор тот что в прицепе ?
На картинке показана загрузка созданного UI-шного файла в конфигурацию. Всё предельно просто ...

А зачем плагин ? Это Исполнитель сделает ... см.ниже. (или моя твоя не понимайт <_< )
Аналогом tooltip/json видимо является динамич-е свойство Bit ?!

Вот функция мапирования с частичным парсингом. Лишнее убрано.
В заремленой строке со стрелкой (valB) имеем возможность достать свойство Bit и его значение.

Раскрывающийся текст

// Связываем поля формы с Моделью
void fpd::mapDynaProperty()
{
    int i, x, Id, nCnt;
    QString aStr, aFld;
    QVariant val, valB;
    QObject *wo;

    // ...

    QSqlRecord curRecord = model->d->tRecord;

    // ...

    nCnt = formWidgets.count();

    for(i = 0;i < nCnt;i++)
    {
        aStr = formWidgets.at(i)->metaObject()->className();
        if (aStr == getCTagByClass(md_TableView))
            continue;

        wo = formWidgets.at(i);
        val = wo->property("Idd");

        if (!val.isValid())
            continue;

        Id = val.toInt();
        aFld = QString("fld_%0").arg(Id);  // Field Name in DB


        x = model->record().indexOf(aFld);

        if (x < 0)
        {
            QMessageBox::warning(dParent, dParent->tr("Fin-Pro"),
                         dParent->tr("DataMapper - Field id = %0 Not Found in Form !!!").arg(Id));
            continue;
        }


        if (!aStr.compare(getCTagByClass(md_CheckBox)))
        {
            QCheckBox *cb = (QCheckBox *) wo;

//          valB = wo->property("Bit");   <---------

            dataMapper->addMapping(cb, x);
        }
        else

        // ...

        else
        if (!aStr.compare(getCTagByClass(md_ComboBox)))
        {
            QComboBox *cb = (QComboBox *) wo;
            dataMapper->addMapping(cb, x, "currentIndex");
        }
    }
}



Ведь всё дело в том, что у всех QCheckBox-сов Idd будет один и тот-же, отличие будет только в значении
динам-го свойства Bit.

Дык вотЪ, я предполагю вариант подмены QCheckBox на что-то типа умного масива, который и будет
админить свойство Bit, и именно его скармливать dataMapper-у ? Как это могло-бы выглядеть ?
Может будут ещё варианты ?

Сообщение отредактировал JohnZ - 9.4.2021, 13:51
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 10.4.2021, 6:18
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2928
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


JohnZ, как достать свойство и установить его программно - это я понимаю. А для отображения его в дизайнере? :) Разве не нужно для этого лезть в файлы IDE или Qt ? Или я отстал от жизни, что-то там поменяли. Я давно с этим не сталкивался

а tooltip - это свойство QWidget, оно в дизайнере уже есть. И туда можно вбить любой текст, в том числе и json, где можно описать что угодно. При этом ничего исправлять не нужно в файлах

Сообщение отредактировал Алексей1153 - 10.4.2021, 6:18
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
JohnZ
  опции профиля:
сообщение 10.4.2021, 13:29
Сообщение #5


Участник
**

Группа: Участник
Сообщений: 139
Регистрация: 19.7.2014
Пользователь №: 4190

Спасибо сказали: 10 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 10.4.2021, 6:18) *
JohnZ, как достать свойство и установить его программно - это я понимаю. А для отображения его в дизайнере? :) Разве не нужно для этого лезть в файлы IDE или Qt ? Или я отстал от жизни, что-то там поменяли. Я давно с этим не сталкивался

Дык Дизайнер его и так, за безплатно отображает :D ... и никуда не надо лезть.
Цитата
а tooltip - это свойство QWidget, оно в дизайнере уже есть. И туда можно вбить любой текст, в том числе и json, где можно описать что угодно. При этом ничего исправлять не нужно в файлах

Динамические св-ва в дизайнере могут быть и строкового типа, как и tooltip, но зачем ? ... если уже есть/создано св-во Bit ?!

Нужен умный масив в объекте, который скармливаем dataMapper-у, и он будет хранить Idd и указатели на QCheckBox-ы на форме.
Что-то типа этого ... Пока на ум ничего более не приходит :mellow:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 11.4.2021, 7:05
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2928
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(JohnZ @ 10.4.2021, 15:29) *
Дык Дизайнер его и так, за безплатно отображает . Промоушен работает - им пользуюсь

почему-то у меня не отображает. И никогда это не работало. Может - это было в старых креаторах? У меня сейчас QtCreator 4.13.2

специально попробовал сделать класс со свойствами, сделал промоушен. Нифига в свойствах в таблице не отобразилось
#pragma once

#include <QLabel>

class CMyWidget:public QLabel
{
    Q_OBJECT
    Q_PROPERTY(Mode     mode        READ getMode        WRITE setMode);
    Q_PROPERTY(QString  extension   READ getExtension   WRITE setExtension)
    Q_ENUMS(Mode)

public:
    using QLabel::QLabel;
    enum class Mode
    {
        Mode_1,
        Mode_2,
        Mode_3,
    };

private:
    Mode mode{};
    QString extension;


    void setMode(const Mode val)
    {
        mode=val;
    }
    Mode getMode() const
    {
        return mode;
    }

    void setExtension(const QString& ext)
    {
        extension=ext;
    }

    QString getExtension() const
    {
        return extension;
    }
};


но, допустим, у тебя это работает, ок.


Цитата(JohnZ @ 10.4.2021, 15:29) *
Нужен умный масив в объекте, который скармливаем dataMapper-у, и он будет хранить Idd и указатели на QCheckBox-ы на форме.

что имеется в виду? Нужно в рантайме собрать в одну таблицу список значений этих свойств у всех контролов?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
JohnZ
  опции профиля:
сообщение 12.4.2021, 17:54
Сообщение #7


Участник
**

Группа: Участник
Сообщений: 139
Регистрация: 19.7.2014
Пользователь №: 4190

Спасибо сказали: 10 раз(а)




Репутация:   0  


Алексей, Вот теперь я понял, что моя <--> твоя не понимайт :rolleyes:

Перечитай первую месагу. Видимо я там чего-то упустил ...

Вот смотри, в QT-Дизайнере я сделал форму, на которой лежит куча QCheckBox-в, которые в БД находятся в ОДНОМ
поле, т.е. по-сути упакованы в один INT. Каждому QCheckBox-у я добавил дин-е св-во Idd и Bit (на картинке обведены
красным). Далее этот файл формы грузится в конфигурацию Конфигуратором. (показано на второй картинке) и далее
уже Исполнитель выполняя полученную т.о. xml-конфигурацию, показывает эту форму, и читает/сохраняет значения в/из БД.

Судя по "Промоушен работает - им пользуюсь." -> Как я тебя понял, ты полагаешь что я должен был *.h файл этой формы положить в Исполнителя чтобы эту форму показать и с ней работать ? Дык нет, всё сделано динамически, и если
мне не изменяет склероз. то ты-же мне и подсказывал ( MVC & QDataWidgetMapper ) как это можно было-бы реализовать.

Всю работу по обмену Модель <-> БД у меня выполняет QDataWidgetMapper (кусок исходника выше) но не устраивает
dataMapper->addMapping(cb, x), т. к. нет доп. параметра, в который можно было-бы положить значение Bit !
Именно по этой причине приходится каждый раз делать это скриптом, а хотелось-бы что-бы Исполнитель
(т.е. Платформа) делал эту работу так-же динамически, БЕЗ необходимости использования скрипта :rolleyes:

Сумбурно, но что-то типа этого, схематично ...

class CMyWidget : public QCheckBox
{
    Q_OBJECT
    Q_PROPERTY(uint32  Field    READ value    WRITE setValue);


public:
    void setIdd(int val)
    {
        Idd=val;
    }

    void valueIdd()
    {
        return Idd;
    }


    uint32 value() const
    {
                bitField = 0;
                for (int i = 0;i < 32;i++)
                {
                     if (cbMAS[i] == NULL) break;
                     bitField |= cbMAS[i]->value() << i;
                }

        return bitField;
    }

    void setValue(uint32 val)
    {
        bitField=val;
    }


        /////////////////////////////////////////////////////////////////////

        void MYaddMapping(QCheckBox *cb, int sec, int Bit)  // ???
        {
               if (cb->getIdd() !=  Idd)   // Не то поле БД
           return;

                for (int i = 0;i < 32;i++)
                {
                     if (cbMAS[i] == NULL)
                     {
                          cbMAS[i] = cb;
                          cb->setValue(( bitField >> i) & 0x01  );
                          break;
                      }
                }

                // ...
        }

private:

   int Idd; // field id in DB && on form

   uint32  bitField;  // Value in DB

  QCheckBox *cbMAS[32];  //  Bit-s in bitField, if exist

};


Цитата
Цитата(JohnZ @ 10.4.2021, 15:29) *
Нужен умный масив в объекте, который скармливаем dataMapper-у, и он будет хранить Idd и указатели на QCheckBox-ы на форме.

что имеется в виду? Нужно в рантайме собрать в одну таблицу список значений этих свойств у всех контролов ?


ИМЕННО ! Только видимо не в таблицу а массив, и в/из него упаковывть / расупаковывть значения в один uint32, который по-идее должен мапится QDataWidgetMapper-ом, но мы ему должны подсунуть на мапинг что-то типа того что выше !

QDataWidgetMapper не знает о том, что значения нескольких QCheckBox-ов упакованы в ОДИН uint32 ...
Это сейчас делает скрипт ...

Удачи !

Сообщение отредактировал JohnZ - 12.4.2021, 17:59
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 13.4.2021, 9:09
Сообщение #8


фрилансер
******

Группа: Участник
Сообщений: 2928
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


JohnZ, ну, хорошо. Будем считать, что я не осилил :D
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
JohnZ
  опции профиля:
сообщение 13.4.2021, 11:14
Сообщение #9


Участник
**

Группа: Участник
Сообщений: 139
Регистрация: 19.7.2014
Пользователь №: 4190

Спасибо сказали: 10 раз(а)




Репутация:   0  


Я нисколько не сомневаюсь что ты меня правильно понял, но ведь решения пока так и нет ...
Видимо придётся что-либо "мутить" с QDataWidgetMapper-ом ... :(
Я пока другого варианта в упор не вижу ...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 13.4.2021, 17:33
Сообщение #10


фрилансер
******

Группа: Участник
Сообщений: 2928
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


JohnZ, нет, я на самом деле не понял ТЗ )) Ты меня переоцениваешь. С классом QDataWidgetMapper ранее не сталкивался, но сейчас в справке почитал, вроде понял, для чего он - вроде как листалка записей из таблицы, при этом поля записи отображаются в нужном виджете на форме.

Позвал телепатов, они предполагают, что проблема именно в том, что
Цитата(JohnZ @ 12.4.2021, 19:54) *
значения нескольких QCheckBox-ов упакованы в ОДИН uint32

то есть, вместо нескольких полей в БД, как это было бы правильно, используется одно поле, в котором отдельные биты - это отдельные данные

Телепаты наметили несколько путей решения проблемы:

путь 1) переконвертировать таблицу БД и разбить скомканное поле на отдельные поля (идеальный вариант, как по мне. Но требует переработать все запросы, которые касаются данного поля)

путь 2) в конструкторе диалога для каждого мапленного виджета добавить (setProperty) свойство (bitIndex) и как-то это дело обрабатывать на отрезке пути "виджет"<-->"record" (тут телепаты за нехваткой знаний о QDataWidgetMapper умолкают)

путь 3) телепаты знают, что все кутешные SQL-модели предназначены для самых банальных случаев с небольшими объёмами данных. И телепаты предлагают использовать старый добрый советский способ: обработать событие изменения QSpinBox, достать запись из БД по текущему ID, разложить поля в виджеты. Если что-либо редактируется, взводится какой-то флажок. Если есть попытка сменить запись, когда есть редактирвоанные данные, то запись сначала перезаписывается новыми данными

Сообщение отредактировал Алексей1153 - 13.4.2021, 17:35
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 26.10.2021, 11:24