Название: делегаты, непонятное поведение Отправлено: PavelVX от Ноября 24, 2010, 12:29 Я только начал осваивать Qt. Взял пример и начал его щупать, перекраивать и наткнулся на странности.
Пример из инета, коннектимся к PostgreSQL: MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QTextCodec *codec = QTextCodec::codecForName("CP1251"); QTextCodec::setCodecForTr(codec); QTextCodec::setCodecForCStrings(codec); QSqlDatabase db = QSqlDatabase::addDatabase("QODBC"); db.setDatabaseName("test.dsn"); db.setUserName("user"); db.setPassword(""); if (!db.open()) { QMessageBox msgBox; msgBox.setText(db.lastError().text()); QStringList drivers = QSqlDatabase::drivers(); msgBox.exec(); } QSqlRelationalTableModel * albumsRelation = new QSqlRelationalTableModel(0); albumsRelation->setTable("public.albums"); // albumsRelation->setRelation(1, QSqlRelation("public.polu1", "\"KODPL\"", "\"NAIM\"")); albumsRelation->setRelation(1, QSqlRelation("public.\"vw_polu1\"", "KODPL", "NAIM")); albumsRelation->select(); albumsRelation->setEditStrategy(QSqlTableModel::OnRowChange); QTableView * view = new QTableView(0); view->setModel(albumsRelation); view->setColumnHidden(0, true); view->setWindowTitle("Ti test"); QSqlRelationalDelegate * delegate = new QSqlRelationalDelegate(view); view->setItemDelegate(delegate); view->show(); } 1. albumsRelation->setRelation(1, QSqlRelation("public.\"vw_polu1\"", "KODPL", "NAIM")); - в дальнейшем, у этого делегата можно выбрать только из списка значение, перетягивая скроллинг, нельзя сделать выбор начав печатать. 2. А теперь самое интресное/непонятное: у меня в таблицах очень много полей в разном регистре. Постгре их различает. То есть NAIM != naim. Но если создавать отношение так: albumsRelation->setRelation(1, QSqlRelation("public.polu1", "\"KODPL\"", "\"NAIM\""));, то оно вообще не создастся. Поэтому пошел на изврат и создал view. Дак вот: если у вью сделать все поля в разном регистре, то отношение не работает, если KODPL сделать в нижнем регистре, а NAIM в верхнем, то не сохраняет значение. Если все сделать в нижнем регистре. то все сохраняет. Это глюк или фича? И как это обойти? Название: Re: делегаты, непонятное поведение Отправлено: crossly от Ноября 24, 2010, 13:27 скорее фитча.... написать свой делегат который будет соответствовать вашим требования... QODBC здесь не лучший вариант... для Postgre есть драйвер
Название: Re: делегаты, непонятное поведение Отправлено: PavelVX от Ноября 24, 2010, 13:35 Если я правильно понял, то под винду дрова для постгри надо компилить самому. Это пока проблема. В дальнейшем может и займусь этим. Пока надо с самим Qt разобраться, понять, подходит он для наших задач или нет.
Название: Re: делегаты, непонятное поведение Отправлено: PavelVX от Ноября 26, 2010, 11:56 А как эту фичу обойти-то??? Получается, что придется постоянно писать вьюхи что ли? И не получится напряму цеплять таблицы, если названия полей таблицы в верхнем регистре?
Название: Re: делегаты, непонятное поведение Отправлено: crossly от Ноября 26, 2010, 12:20 Цитировать написать свой делегат который будет соответствовать вашим требованиям... Название: Re: делегаты, непонятное поведение Отправлено: PavelVX от Декабря 06, 2010, 11:06 доброго времени суток!
Почти разобрался с делегатом на основе QComboBox. Но помогите, пожалуйста, в следующем моменте: MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QSqlRelationalTableModel * albumsRelation = new QSqlRelationalTableModel(0); albumsRelation->setTable("public.albums"); albumsRelation->setRelation(1, QSqlRelation("public.polu1", "\"KODPL\"", "\"NAIM\"")); albumsRelation->select(); albumsRelation->setEditStrategy(QSqlTableModel::OnRowChange); ui->TableView->setModel(albumsRelation); ComboBoxDelegate * comboDelegate = new ComboBoxDelegate(this); ui->TableView->setItemDelegateForColumn( 1, comboDelegate ); } void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QComboBox *comboBox = static_cast<QComboBox*>(editor); int value = index.model()->data(index, Qt::EditRole).toInt(); //тут первая проблема comboBox->setCurrentIndex(value); //тут вторая проблема }; Тут я запутался капитально :(. 1. Как мне правильно получить значение ключа(kodpl) в value? Оно берется текстовым из релатион походу(naim)? 2. Как мне правильно спозиционировать значение при открытии делегата? Название: Re: делегаты, непонятное поведение Отправлено: shirushizo от Декабря 06, 2010, 18:18 Тут я запутался капитально :(. 1. Как мне правильно получить значение ключа(kodpl) в value? Оно берется текстовым из релатион походу(naim)? 2. Как мне правильно спозиционировать значение при открытии делегата? Решение обоих проблем: Код: QComboBox *comboBox = static_cast<QComboBox*>(editor); //для наследников QObject советуют использовать qobject_cast Название: Re: делегаты, непонятное поведение Отправлено: PavelVX от Декабря 07, 2010, 12:07 Если я правильно понял, то:
QComboBox *comboBox = static_cast<QComboBox*>(editor); //для наследников QObject советуют использовать qobject_cast QString value = index.model()->data(index, Qt::EditRole).toString(); //получил текстовое значение ячейки comboBox->setCurrentIndex(combo->findText(value)); //установил текущую позицию как надо //тогда получается, что для установки нового значения в model нужно сделать так: void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *comboBox = qobject_cast<QComboBox*>(editor); model->setData(index, comboBox->currentText(), Qt::EditRole); }; //как-то странно это. возвращать текст, а не значение. Или после МС Аксеса просто непривычно Название: Re: делегаты, непонятное поведение Отправлено: shirushizo от Декабря 07, 2010, 18:27 Можешь посмотреть как реализовано в QSqlRelationalDelegate. Установка значения там реализована через методы
Код: QSqlTableModel QSqlRelationalTableModel::relationModel(int column) Находятся %QtDir%/qt/src/sql/models/qsqlrelationaldelegate.h Еще кто-то на форуме свой делаегат предлагал, там в зависимости от типа поля - разные редакторы. Название: Re: делегаты, непонятное поведение Отправлено: PavelVX от Декабря 08, 2010, 11:11 Не получается каменный цветок! Ну не лезет никак :(.
Придется пост наверное продублировать и в MCV. %QtDir%/qt/src/sql/models/qsqlrelationaldelegate.h - его я разбирал, и вставлять пытался. Но не получаю нужного значения. Если у меня в модели комбобокса 2 колонки, видимаю вторая колонка, как мне получить соответствующее значение из первой колонки? Может кто-нить пример привести? ComboBoxDelegate::ComboBoxDelegate(QObject *parent) { DelegateModel = new QSqlQueryModel; DelegateModel->setQuery("select \"KODPL\", \"NAIM\" from public.polu1 order by \"NAIM\""); }; QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option , const QModelIndex & index ) const { QComboBox *editor = new QComboBox(parent); editor->setModel(DelegateModel); editor->setModelColumn(1); //показывать текст return editor; }; void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QComboBox *comboBox = qobject_cast<QComboBox*>(editor); //для наследников QObject советуют использовать qobject_cast QString value = index.model()->data(index, Qt::EditRole).toString(); comboBox->setCurrentIndex(comboBox->findText(value)); }; void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *comboBox = qobject_cast<QComboBox*>(editor); // model->setData(index, comboBox->currentText(), Qt::EditRole); model->setData(index, comboBox->currentIndex(), Qt::EditRole); /*тут и начинаются проблемы! Не могу прописать значения никак. В model нужно положить значение из первой колонки комбобокса. Иначе облом. что правильно. Но как его получить-то??? */ }; void ComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const { editor->setGeometry(option.rect); }; Название: Re: делегаты, непонятное поведение Отправлено: asvil от Декабря 08, 2010, 12:23 Код: ComboBox->model()->index(ComboBox->currentIndex(), *НОМЕР_ПЕРВОЙ_КОЛОНКИ*).data(); Название: Re: делегаты, непонятное поведение Отправлено: PavelVX от Декабря 08, 2010, 13:26 Филоненко Михаил, shirushizo, огромное, огромное спасибо!!! :)
Вроде все заработало как надо. Теперь буду делать GUI + механику там. попутно разбираясь в QT. Но вообще это как-то странно, после МС Аксеса данный метод кажется варварским :). Название: Re: делегаты, непонятное поведение Отправлено: asvil от Декабря 08, 2010, 15:28 Я переводил, если это можно так назвать, приложение с аксеса в postgresql, qt и в целом впечатления положительные стали только после того, как написал некоторую аксесо-подобную прослойку (модели, представления, qt script вместо vba).
Название: Re: делегаты, непонятное поведение Отправлено: PavelVX от Декабря 09, 2010, 06:37 Михаил, у меня именно такая же цель. Связку MS SQL Server + MS Access перевожу на PostgreSQL + Qt. Сервер уже перевел, заодно сбросив туда почти все пересчеты. Теперь надо переводить GUI. Правда я еще не тестил Qt GUI под линухом. Хочется сделать проект, который будет компилиться и использоваться и под вин и лиль платформой, с последующим полным переходом на линь.
|