Russian Qt Forum

Qt => Базы данных => Тема начата: trenkinan от Май 06, 2010, 00:14



Название: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 06, 2010, 00:14
Есть таблица  QSqlQueryModel+ QTableView.
Все отображается, все рады. Нужно сделать ячейки редактируемыми. Разные столбцы буду редактировать разными виджентами(для начала редактирование текста, далее по аналогии QSpinBox думаю прикручу). Объясните по порядку ход действий. Пока разбор примеров ни к чему не привел. Приведеите пример как реализовать делегат для редакирования столбца "Фамилия". Заранее спасибо.


Название: Re: Помогите разобраться с делегатами
Отправлено: alexman от Май 06, 2010, 08:02
Сначала поиском нужно попробовать воспользоваться!
http://doc.crossplatform.ru/qt/4.5.0/model-view-delegate.html


Название: Re: Помогите разобраться с делегатами
Отправлено: cya-st от Май 06, 2010, 10:06
Есть в книге пример "Бланшет,Саммерфилд - QT4 Программирование GUI на С++.2ed", доходчиво описано.


Название: Re: Помогите разобраться с делегатами
Отправлено: crossly от Май 06, 2010, 14:10
товарисч.... для начала надо сделать модель редактируемой.... т.е. вам надо унаследоватся от QSqlQueryModel переопределить как минимум методы setData и flags ....


Название: Re: Помогите разобраться с делегатами
Отправлено: vpara от Май 06, 2010, 17:39
У бланшета всё понятно ... но предполжим мне нужно иметь чтото типа QDateEdit (с календарем со всеми делами) в столбце QTableView ... начал прикручивать пример для своего случая ... пока безуспешно ... может это можно сделать както проще?


Название: Re: Помогите разобраться с делегатами
Отправлено: alexman от Май 06, 2010, 20:08
А в чем проблема?


Название: Re: Помогите разобраться с делегатами
Отправлено: cya-st от Май 06, 2010, 20:31
У бланшета всё понятно ... но предполжим мне нужно иметь чтото типа QDateEdit (с календарем со всеми делами) в столбце QTableView ... начал прикручивать пример для своего случая ... пока безуспешно ... может это можно сделать както проще?
У Бланшета в книге есть глава "Реализация пользовательских делегатов", где вполне доступно изложено с примером.


Название: Re: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 06, 2010, 23:28
перешел на QSqlTableModel и все стало хорошо, заработал QLine edit и QSpinbox(правда его придетс доточить для работы с целыми) Ну и хотелось бы календарик создать, будем пытаться... Всем спасибо


Название: Re: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 07, 2010, 18:58
На ночь глядя не заметил, что данные то редактируются, только вот изменения  сохраняются не всегда... иногда пишет в qDebug   :
Код:
Object::connect: No such slot MainWindow::currentChanged() in mainwindow.cpp:163
Object::connect:  (receiver name: 'MainWindowClass')
QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.

а иногда нормально...парадокс.  Обычно ошибка появляется при первом запуске проекта, при последующих данные сохраняются 


Название: Re: Помогите разобраться с делегатами
Отправлено: Marat(Qt) от Май 08, 2010, 09:31
Насчет сохранения изменений - тебе вероятно нужно про QSqlTableModel::setEditStrategy почитать, а то что у тебя вызывается слот currentChanged - которого на самом деле нет, это вроде как к сохранению данных не относится


Название: Re: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 08, 2010, 12:30
использую такую:
Код:
 model1->setEditStrategy(QSqlTableModel::OnRowChange);


Название: Re: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 08, 2010, 15:50
Хорошо, с этим вроде как разобрались. Теперь вопрос, как собственно прикрутить красивый календарь к 9-му столбцу?
Создаю класс делегат в хедере:
Код:
class Calendar : public QItemDelegate {
        Q_OBJECT
    public:
      Calendar(bool calpopup = true,
                     QObject *parent = 0);
         QWidget *createEditor(
                    QWidget *parent,
                    const QStyleOptionViewItem &option,
                    const QModelIndex &index);
         void setEditorData(QWidget *editor,
                           const QModelIndex &index);
        void setModelData(QWidget *editor,
                          QAbstractItemModel *model,
                          const QModelIndex &index);
        void updateEditorGeometry(
                QWidget *editor,
                const QStyleOptionViewItem &option,
                const QModelIndex &index);
    private:
        bool m_calpopup;
    };

Далее почитав примеров так и не понял что делать


Название: Re: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 10, 2010, 10:16
 ладно, тогда вот вопрос: Можно ли без использования внешних ключей( и соответственно дополнительных таблиц ) реализовать выпадающий список?


Название: Re: Помогите разобраться с делегатами
Отправлено: alexman от Май 10, 2010, 10:38
ладно, тогда вот вопрос: Можно ли без использования внешних ключей( и соответственно дополнительных таблиц ) реализовать выпадающий список?
Это combo box делегат: http://doc.qt.nokia.com/4.6/widgets-icons-imagedelegate-cpp.html


Название: Re: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 10, 2010, 11:55
Ok. Пишу делегат как в примере:
Код
C++ (Qt)
ImageDelegate::ImageDelegate(QObject *parent)
    : QItemDelegate(parent)
{
}
 
QWidget *ImageDelegate::createEditor(QWidget *parent,
                                     const QStyleOptionViewItem & /* option */,
                                     const QModelIndex &index) const
{
    QComboBox *comboBox = new QComboBox(parent);
    if (index.column() == 6) {
        comboBox->addItem(tr("Да"));
        comboBox->addItem(tr("Нет"));
    }
 
    connect(comboBox, SIGNAL(activated(int)), this, SLOT(emitCommitData()));
 
    return comboBox;
}
 
void ImageDelegate::setEditorData(QWidget *editor,
                                  const QModelIndex &index) const
{
    QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
    if (!comboBox)
        return;
 
    int pos = comboBox->findText(index.model()->data(index).toString(),
                                 Qt::MatchExactly);
    comboBox->setCurrentIndex(pos);
}
 
void ImageDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                 const QModelIndex &index) const
{
    QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
    if (!comboBox)
        return;
 
    model->setData(index, comboBox->currentText());
}
 
void ImageDelegate::emitCommitData()
{
    emit commitData(qobject_cast<QWidget *>(sender()));
}
 
Но ничего не происходит


Название: Re: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 10, 2010, 12:17
и вот что интересно... если написать
Код
C++ (Qt)
qDebug()<<index.column();
то он ничего не выводит...в общем из-за чего может возникать проблема с индексами?


Название: Re: Помогите разобраться с делегатами
Отправлено: alexman от Май 10, 2010, 15:32
Весь пример прикрепи?


Название: Re: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 12, 2010, 11:30
вот нужная часть :
Код
C++ (Qt)
model1 = new QSqlTableModel;
   proxyModel = new QSortFilterProxyModel(this);
   QTextCodec::setCodecForCStrings(QTextCodec::codecForName("windows-1251"));
   model1->setTable("peoples5");
   model1->select();
   ui->mytable->setModel(model1);
   ui->mytable->setEditTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed);
 
row = model1->rowCount();
qDebug()<<row;
createContextMenu();
        proxyModel->setSourceModel(model1);
        ui->mytable->setModel(proxyModel);
   QTextCodec::setCodecForTr(QTextCodec::codecForName("windows-1251"));
  model1->setHeaderData(6, Qt::Horizontal,
                  tr("Женат/замужем"));
   model1->setHeaderData(8, Qt::Horizontal,
                  tr("Дата рождения"));
 
   view.setModel(model1);
     QSqlQuery temp;
}
 
   else qDebug()<<"Error in opening"<<db.lastError();
}
void MainWindow::createContextMenu()
{
 
   ui->mytable->addAction(insertrow);
   ui->mytable->addAction(deleterow);
}
 
 
 
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
 
 
//combobox delegate
 
ImageDelegate::ImageDelegate(QObject *parent)
    : QItemDelegate(parent)
{
}
 
QWidget *ImageDelegate::createEditor(QWidget *parent,
                                     const QStyleOptionViewItem & /* option */,
                                     const QModelIndex &index) const
{
    QComboBox *comboBox = new QComboBox(parent);
    if (index.column() == 1) {
        comboBox->addItem(tr("Да"));
 
        comboBox->addItem(tr("Нет"));
    }
qDebug()<<index.column();
    connect(comboBox, SIGNAL(activated(int)), this, SLOT(emitCommitData()));
 
    return comboBox;
}
 
void ImageDelegate::setEditorData(QWidget *editor,
                                  const QModelIndex &index) const
{
    QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
    if (!comboBox)
        return;
 
    int pos = comboBox->findText(index.model()->data(index).toString(),
                                 Qt::MatchExactly);
    comboBox->setCurrentIndex(pos);
}
 
void ImageDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                 const QModelIndex &index) const
{
    QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
    if (!comboBox)
        return;
 
    model->setData(index, comboBox->currentText());
}
 
void ImageDelegate::emitCommitData()
{
    emit commitData(qobject_cast<QWidget *>(sender()));
}
 
//end of delegate
 


Название: Re: Помогите разобраться с делегатами
Отправлено: alexman от Май 12, 2010, 11:52
А где вызов void QAbstractItemView::setItemDelegate ( QAbstractItemDelegate * delegate )?


Название: Re: Помогите разобраться с делегатами
Отправлено: trenkinan от Май 12, 2010, 23:46
нету=) как делать?


Название: Re: Помогите разобраться с делегатами
Отправлено: cya-st от Май 13, 2010, 10:34
нету=) как делать?
Определяеш делегат: class MyDelegate : public QItemDelegate.... Ты книгу читал? Прочитай книгу, быстрее будет.


Название: Re: Помогите разобраться с делегатами
Отправлено: lit-uriy от Май 13, 2010, 13:21
>>QTextCodec::setCodecForTr(QTextCodec::codecForName("windows-1251"));
А за каким лешим ты посредь программы кодек меняешь? Любишь блох искать?


Название: Re: Помогите разобраться с делегатами
Отправлено: alexman от Май 13, 2010, 13:22
ui->mytable->setItemDelegate( new ImageDelegate( ui->mytable ) );


Название: Re: Помогите разобраться с делегатами
Отправлено: lit-uriy от Май 13, 2010, 13:25
>>нету=) как делать?
Дык, метод, который указал alexman, вызови у представления, которое ты используешь. Для чего-то ты ведь делал делегат, но не используешь его