Russian Qt Forum

Qt => Model-View (MV) => Тема начата: silart от Ноябрь 10, 2010, 13:34



Название: Как сделать универсальный делегат?
Отправлено: silart от Ноябрь 10, 2010, 13:34
Добрый день!

Ситуация такая. Есть QSqlTableModel. Есть универсальный диалог для редактирования справочников. Он создается, принимает модель, отображает содержимое справочника и позволяет редактировать данные. Вот только вышла одна неприятность: стандартный делегат плохо отображает и редактирует поля тип bool. То есть он отображает единицу, если true и 0, если false.
Мне нужно, чтобы в булевом поле был чекбокс, и при этом он там появлялся сам. То есть чтобы мне не приходилось указывать вручную какой столбец имеет булевое поле. Каковы есть способы решения данной проблемы:
1. Унаследовать класс от класса модели, а в порожденном классе переопределить метод
Код:
virtual Qt::ItemFlags flags( const QModelIndex & index ) const
Не допустимо переопределять каждый раз класс модели, когда нужно внести изменения в отображении какого-либо поля. Такой подход приводит к множеству классов, которые засоряют пространство имен.

2. Создать делегат и установить его для конкретного столбца, имеющего тип bool.
Но тогда нужно знать какой столбец имеет булевый тип, а он может отличаться от справочника к справочнику. Диалог должен быть универсальным.
Этот подход также приводит к возникновению множества классов, ведь в будущем может понадобиться изменить редактирование какого-нибудь другого типа данных.

Нужно сделать такой делегат, чтобы он был у наследован от QItemDelegate, потому что большинство типов данных он хорошо редактирует.
Это должен быть один класс, и задаваться он должен для всех столбцов. Делегат должен сам определять тип столбца, и создавать нужный виджет, в зависимости от типа данных.


Название: Re: Как сделать универсальный делегат?
Отправлено: Пантер от Ноябрь 10, 2010, 13:51
Ничего сложного тут нет. Я делал подобное.
http://gitorious.org/qdbfredactor/qdbfredactor/blobs/master/src/dbfredactordelegate.h
http://gitorious.org/qdbfredactor/qdbfredactor/blobs/master/src/dbfredactordelegate.cpp
Посмотри и подкорректируй под свои нужды.
Там, где я использую switch (m_redactor->field(index.column()).type) { тебе нужно будет проверять Type QVariant::type () const у index.data ()


Название: Re: Как сделать универсальный делегат?
Отправлено: silart от Ноябрь 17, 2010, 12:48
Пантер!

Получается, что какой выбрать виджет, определяется по типу варионта?

Код:
	QVariant value = index.data();
QVariant::Type t = value.type();

Подскажите пожалуйста, у меня access'овская база, и есть поле булевого типа. Но вот только t у меня имеет тип вместо bool UInt. От чего это зависит, как думаете? От базы? Можно ли принудительно в модели задать тип столбца?


Название: Re: Как сделать универсальный делегат?
Отправлено: Пантер от Ноябрь 17, 2010, 13:12
access - мрак. :) Да, это из-за нее.
Даже не знаю, как с аксесом это провернуть. А UInt только на булевые возвращается? Может, просто на него реагировать?


Название: Re: Как сделать универсальный делегат?
Отправлено: silart от Ноябрь 17, 2010, 13:22
access - мрак. :) Да, это из-за нее.
Даже не знаю, как с аксесом это провернуть. А UInt только на булевые возвращается? Может, просто на него реагировать?

Да язнаю, что мрак!  ;D Просто это пока тестовая база.
Честно говоря, не знаю, у меня сейчас есть только строковые типы, целочисленные и булевые, которые отображаются, как UInt.
Неужели никак нельзя повлиять на модель, чтобы задать нужный тип столбца?


Название: Re: Как сделать универсальный делегат?
Отправлено: Пантер от Ноябрь 17, 2010, 13:43
Лучше используй SQLite.


Название: Re: Как сделать универсальный делегат?
Отправлено: silart от Ноябрь 19, 2010, 09:17
Пантер!
Поменял я базу на SQLite. Да только та же история. Теперь только вместо Uint, тип булевого поля - LongLong.  ???
Я ваще ничего не понимаю. Может я неправильно таблицу создаю? Хотя создавал в графическом редакторе. В общем вот SQL код создания таблицы:
Код:
CREATE TABLE [Operators] (
[OperatorID] INTEGER  PRIMARY KEY NOT NULL,
[OperatorName] VARCHAR(60)  NOT NULL,
[OperatorPassword] VARCHAR(16)  NULL,
[IsAdministrator] BOOLEAN  NOT NULL
)


Название: Re: Как сделать универсальный делегат?
Отправлено: Пантер от Ноябрь 19, 2010, 10:35
Блин, забыл, что SQLite не поддерживает типы данных. :)
Есть вариант использовать Firebird, там точно есть.


Название: Re: Как сделать универсальный делегат?
Отправлено: silart от Ноябрь 19, 2010, 11:37
То есть как это не поддерживает? Как без них?
А файрберд без проблем к Qt прикрутится?
Нужно драйвер собирать? Подскажите пожалуйста, как это лучше сделать?
Нужен файрберд встроеный, по типу SQLite.


Название: Re: Как сделать универсальный делегат?
Отправлено: crossly от Ноябрь 19, 2010, 11:39
в sqlite типы данных довольно условные.... firebird embeded + QIBASE


Название: Re: Как сделать универсальный делегат?
Отправлено: Пантер от Ноябрь 19, 2010, 11:49
Драйвер собираешь вот так:
http://prog.org.ru/wiki/index.php?title=%D0%A1%D0%B1%D0%BE%D1%80%D0%BA%D0%B0_%D0%B4%D1%80%D0%B0%D0%B9%D0%B2%D0%B5%D1%80%D0%B0_Firebird_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%82%D0%BE%D1%80%D0%BE%D0%BC_MinGW_32. (http://prog.org.ru/wiki/index.php?title=%D0%A1%D0%B1%D0%BE%D1%80%D0%BA%D0%B0_%D0%B4%D1%80%D0%B0%D0%B9%D0%B2%D0%B5%D1%80%D0%B0_Firebird_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%82%D0%BE%D1%80%D0%BE%D0%BC_MinGW_32.)
Потом подменяешь dll'ку firebird'а на embedded и он станет встроенным. Нюанс в том, что файл бд не сможет быть расположен в сети (даже на сетевом диске).


Название: Re: Как сделать универсальный делегат?
Отправлено: silart от Ноябрь 19, 2010, 13:26
Товарищи, подскажите пожалуйста.
Что-то сходу в нее я не въехал, в эту базу Firebird. Скачал утилиту Interbase&Firebird Development Studio. Установил firebird как сервер. И даже что-то не могу создать новую базу на сервере.  :-\

Как происходит установка базы инсталлятором? Сильно сложная? Я имею в виду сложно ли поставлять базу firebird + сервер в своем инсталляционном пакете?
Вот к примеру SQLite, достаточно файл базы скопировать при установке и все. И access также. А вот как обстоят дела с Firebird?


Название: Re: Как сделать универсальный делегат?
Отправлено: crossly от Ноябрь 19, 2010, 13:41
я так полагаю клиент-сервер вам не нужен.... тогда firebird embedded ... достаточно положить dll в папку к программе... а по поводу создания бд тож проде ничего сложного... открываем isql и пишем create database .....


Название: Re: Как сделать универсальный делегат?
Отправлено: silart от Ноябрь 19, 2010, 13:46
crossly!
Подскажите пожалуйста, каким графическим менеджером баз данных вы пользуетесь?
Или вы только isql.exe используете?


Название: Re: Как сделать универсальный делегат?
Отправлено: Пантер от Ноябрь 19, 2010, 13:48
IBExpert используй.


Название: Re: Как сделать универсальный делегат?
Отправлено: crossly от Ноябрь 19, 2010, 13:50
когда то пользовал Interbase&Firebird Development Studio ... в последнее время isql


Название: Re: Как сделать универсальный делегат?
Отправлено: silart от Ноябрь 19, 2010, 13:53
Вот им то я и не смог создать базу.  >:(


Название: Re: Как сделать универсальный делегат?
Отправлено: crossly от Ноябрь 19, 2010, 13:55
а что сложного то??


Название: Re: Как сделать универсальный делегат?
Отправлено: lit-uriy от Ноябрь 20, 2010, 02:32
FlameRobin - бесплатный графический менджер птицы