Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ Помогите с делегатом

Автор: Hepr 20.2.2011, 15:21

Здравствуйте, у меня есть делегат- QTimeEdit, я делегирую его в QTableWidget, фактически за основу я взял делегат QSpinBox'a из примеров Qt, и изменил то что мне надо, но выскакивают ошибки, я меняю код, и ошибки меняются :o:
Вот сам код
delegate.h

#ifndef DELEGATE_H
#define DELEGATE_H

#include <QItemDelegate>
#include <QModelIndex>
#include <QObject>
#include <QSize>
#include <QSpinBox>

//! [0]
class TimeEditDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    TimeEditDelegate(QObject *parent = 0);
    QTime * value;

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const;

    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const;

    void updateEditorGeometry(QWidget *editor,
        const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
//! [0]

#endif

delegate.cpp
#include <QtGui>
#include "delegate.h"


//! [0]
TimeEditDelegate::TimeEditDelegate(QObject *parent)
    : QItemDelegate(parent)
{
}
//! [0]

//! [1]
QWidget *TimeEditDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &/* option */,
    const QModelIndex &/* index */) const
{
    QTimeEdit *editor = new QTimeEdit(parent);
    return editor;
}
//! [1]

//! [2]
void TimeEditDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    * value = index.model()->data(index, Qt::EditRole).toTime();
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->setTime(* value);
}
//! [2]

//! [3]
void TimeEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->interpretText();
    * value = timeEdit->time();
    model->setData(index, value , Qt::EditRole);
}
//! [3]

//! [4]
void TimeEditDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
    editor->setGeometry(option.rect);
}
//! [4]

Скажите пожалуйста, что я делаю неправильно, и объясните как правильно, если не трудно
Вот, какая ошибка выскакивает сейчас

Ошибка 1 error C2248: QVariant::QVariant: невозможно обратиться к private член, объявленному в классе "QVariant" c:\Documents and Settings\hepr\Мои документы\Visual Studio 2008\Projects\asd\asd\delegets\delegate.cpp 87
Заранее спасибо!

Автор: xls 20.2.2011, 16:53

Ты изменяешь член "value" в константных методах, которые потому и константные, что не должны ничего изменять.

Автор: Hepr 20.2.2011, 17:25

А исправьте пожалуйста, как правильно

Автор: Litkevich Yuriy 20.2.2011, 20:48

Гость_Hepr_*, а он тебе как член класса и не нужен. Ты его всё равно всякий раз внутри функции изменяешь и используешь, дак и сделай его локальной переменной функции.

П.С.
И делать его указателем тоже ни к чему, т.к. используется только по значению.

Автор: Hepr 20.2.2011, 22:23

Цитата(Litkevich Yuriy @ 20.2.2011, 20:48) *
Гость_Hepr_*, а он тебе как член класса и не нужен. Ты его всё равно всякий раз внутри функции изменяешь и используешь, дак и сделай его локальной переменной функции.

П.С.
И делать его указателем тоже ни к чему, т.к. используется только по значению.

Это я понимаю, и делаю это для удобства(когда будет работать нормально исправлю), но ошибка возникает, согласитесь не по-этому
Ошибка возникает тут: model->setData(index, value , Qt::EditRole);
А именно на Qt::EditRole, но почему я не понимаю(

Автор: Rocky 20.2.2011, 22:27

Цитата(Гость_Hepr_* @ 20.2.2011, 22:23) *
Ошибка возникает тут: model->setData(index, value , Qt::EditRole);
А именно на Qt::EditRole, но почему я не понимаю(



Цитата(Гость_Hepr_* @ 20.2.2011, 15:21) *
Ошибка 1 error C2248: QVariant::QVariant: невозможно обратиться к private член, объявленному в классе "QVariant" c:\Documents and Settings\hepr\Мои документы\Visual Studio 2008\Projects\asd\asd\delegets\delegate.cpp 87


Где тут написано, что ошибка возникает на Qt::EditRole?

Автор: xls 20.2.2011, 23:15

Переименуй value.

Автор: hepr 20.2.2011, 23:17

Цитата(Rocky @ 20.2.2011, 22:27) *
Цитата(Гость_Hepr_* @ 20.2.2011, 22:23) *
Ошибка возникает тут: model->setData(index, value , Qt::EditRole);
А именно на Qt::EditRole, но почему я не понимаю(



Цитата(Гость_Hepr_* @ 20.2.2011, 15:21) *
Ошибка 1 error C2248: QVariant::QVariant: невозможно обратиться к private член, объявленному в классе "QVariant" c:\Documents and Settings\hepr\Мои документы\Visual Studio 2008\Projects\asd\asd\delegets\delegate.cpp 87


Где тут написано, что ошибка возникает на Qt::EditRole?

Во всяком случае VS мне указывает именно на эту строку
P.S. я разбил model->setData(index, value , Qt::EditRole);
на
model->setData(index,
value ,
Qt::EditRole); // и показало что ошибка в этой строке

Автор: Hepr 20.2.2011, 23:28

Цитата
Переименуй value.

И вправду помогло, а не объясните в чем было проблема, дайте угадаю это была какая-то системная переменная или тп?
А не подскажите как теперь установить делегат в QTableWidget, нужный item(а точнее в column)
P.S. огромное спасибо за помощь, без вас я бы вряд ли сам понял, где собака зарыта

Автор: Litkevich Yuriy 21.2.2011, 11:13

Цитата(Гость_hepr_* @ 21.2.2011, 1:17) *
Qt::EditRole); // и показало что ошибка в этой строке
он просто показал на конец оператора. Си/Си++ компилятор не в силах определить место в строке, только саму строку.

можешь для эксперимента закрывающуюся скобку перенести на другую строку

Автор: Hepr 21.2.2011, 16:14

Здравствуйте, теперь все компилируется нормально, проект запускается, но как только я хочу вызвать делегат выдает ошибку(Нарушение прав доступа при чтении), я понимаю чем это может быть вызвано(обращение не к публичной функции вне класса и тп), но где именно в коде может провоцироваться ошибка, я так и не нашел, помогите пожалуйста
delegate.h

#ifndef DELEGATE_H
#define DELEGATE_H

#include <QItemDelegate>
#include <QModelIndex>
#include <QObject>
#include <QSize>
#include <QSpinBox>

//! [0]
class TimeEditDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    TimeEditDelegate(QObject *parent = 0);
    QTime * val;

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
        const QModelIndex &index) const;

    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
        const QModelIndex &index) const;

    void updateEditorGeometry(QWidget *editor,
        const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
//! [0]

#endif

delegate.cpp
#include <QtGui>
#include "delegate.h"


//! [0]
TimeEditDelegate::TimeEditDelegate(QObject *parent)
: QItemDelegate(parent)
{
}
//! [0]

//! [1]
QWidget *TimeEditDelegate::createEditor(QWidget *parent,
                                        const QStyleOptionViewItem &/* option */,
                                        const QModelIndex &/* index */) const
{
    QTimeEdit *editor = new QTimeEdit(parent);
    return editor;
}
//! [1]

//! [2]
void TimeEditDelegate::setEditorData(QWidget *editor,
                                     const QModelIndex &index) const
{
    * val = index.model()->data(index, Qt::EditRole).toTime();
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->setTime(* val);
}
//! [2]

//! [3]
void TimeEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                    const QModelIndex &index) const
{
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->interpretText();
    * val = timeEdit->time();
    //   model->setData(index, value , Qt::EditRole);
}
//! [3]

//! [4]
void TimeEditDelegate::updateEditorGeometry(QWidget *editor,
                                            const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
    editor->setGeometry(option.rect);
}
//! [4]

main.cpp
#include <QApplication>
#include <QHeaderView>
#include <QItemSelectionModel>
#include <QStandardItemModel>
#include <QTableView>

#include "delegate.h"

//! [0]
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QStandardItemModel model(4, 2);
    QTableView tableView;
    tableView.setModel(&model);

    TimeEditDelegate delegate;
    tableView.setItemDelegate(&delegate);
//! [0]

    tableView.horizontalHeader()->setStretchLastSection(true);

//! [1]
    for (int row = 0; row < 4; ++row) {
        for (int column = 0; column < 2; ++column) {
            QModelIndex index = model.index(row, column, QModelIndex());
            model.setData(index, QVariant((row+1) * (column+1)));
        }
//! [1] //! [2]
    }
//! [2]

//! [3]
    tableView.setWindowTitle(QObject::tr("Spin Box Delegate"));
    tableView.show();
    return app.exec();
}
//! [3]

P.S. заранее огромное спасибо, за потраченное время

Автор: Rocky 21.2.2011, 17:02

рррррр..
В посте номер 1 такой код:

void TimeEditDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    * value = index.model()->data(index, Qt::EditRole).toTime();
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->setTime(* value);
}


В посте номер 11:
void TimeEditDelegate::setEditorData(QWidget *editor,
                                     const QModelIndex &index) const
{
    * val = index.model()->data(index, Qt::EditRole).toTime();
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->setTime(* val);
}


Т.е. воспринято было буквально, value заменен на val. Я бы посоветовал пойти почитать для начала любую книгу "С++ для начинающих" и т.п. В частности что такое указатели, для чего они, как с ними работать и пр. и пр. Иначе код такой потом получится что мама не горюй.

Автор: Hepr 21.2.2011, 17:56

Цитата(Rocky @ 21.2.2011, 17:02) *
рррррр..
В посте номер 1 такой код:
void TimeEditDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    * value = index.model()->data(index, Qt::EditRole).toTime();
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->setTime(* value);
}


В посте номер 11:
void TimeEditDelegate::setEditorData(QWidget *editor,
                                     const QModelIndex &index) const
{
    * val = index.model()->data(index, Qt::EditRole).toTime();
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->setTime(* val);
}


Т.е. воспринято было буквально, value заменен на val. Я бы посоветовал пойти почитать для начала любую книгу "С++ для начинающих" и т.п. В частности что такое указатели, для чего они, как с ними работать и пр. и пр. Иначе код такой потом получится что мама не горюй.

Я как раз после такой книги, и ни смотря на то что я буквально понял подсказку-ошибки больше не выдавалось, и текст начал компилироваться нормально,
И я вроде неплохо варю С++(насколько это возможно для новичка), что такое указатели и как их использовать знаю, просто я Qt совсем не давно начал изучать вот и часто глупости пишу, и все-таки не могли бы подсказать где ошибка, а лучше тыкнуть носом, а то я совсем запутался :mellow:

Автор: Rocky 21.2.2011, 18:06

1. Вижу объявление указателя на класс QTime * val;
А вот где выделяется память под объект класса не увидел. Если здесь охота работать именно с указателями, нужно в конструкторе написать:

QTime * val = new QTime(...);

И потом уже использовать val (*val).

2. Нет никакой необходимости делать переменную член класса QTime * val общедоступной.
3. Нет никакой необходимости вообще использовать переменную-член QTime * val.
4. Нет никакой необходимости использовать переменную QTime * val как указатель (достаточно либо самого объекта, либо константной ссылки на него - в данном случае).
5. Многие куски кода можно переписать так:
    QTimeEdit *editor = new QTimeEdit(parent);
    return editor;

заменить на:
   return new QTimeEdit(parent);


    * val = index.model()->data(index, Qt::EditRole).toTime();
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->setTime(* val);


заменить на:
   QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
if (timeEdit)  timeEdit->setTime(index.model()->data(index, Qt::EditRole).toTime());

и т.д.

Автор: Hepr 21.2.2011, 18:36

Цитата(Rocky @ 21.2.2011, 18:06) *
1. Вижу объявление указателя на класс QTime * val;
А вот где выделяется память под объект класса не увидел. Если здесь охота работать именно с указателями, нужно в конструкторе написать:
QTime * val = new QTime(...);

И потом уже использовать val (*val).

2. Нет никакой необходимости делать переменную член класса QTime * val общедоступной.
3. Нет никакой необходимости вообще использовать переменную-член QTime * val.
4. Нет никакой необходимости использовать переменную QTime * val как указатель (достаточно либо самого объекта, либо константной ссылки на него - в данном случае).
5. Многие куски кода можно переписать так:
    QTimeEdit *editor = new QTimeEdit(parent);
    return editor;

заменить на:
   return new QTimeEdit(parent);


    * val = index.model()->data(index, Qt::EditRole).toTime();
    QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
    timeEdit->setTime(* val);


заменить на:
   QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
if (timeEdit)  timeEdit->setTime(index.model()->data(index, Qt::EditRole).toTime());

и т.д.

Спасибо большое, блин искал в ассистенте что делают те или иные функции, классы, а сам память забыл в конструкторе выделить, спасибо большое

Автор: Hepr 21.2.2011, 22:35

Что бы не открывать новой темы, позвольте задать в этой еще 1 вопрос, как я понимаю значение в ячейке таблицы, по умолчанию имеет тип int, а как можно его переделать в QTime, а то после того как я в делегате, выставлю время, она не сохраняется, там так и остается, то значение в int, что и было

Автор: Алексей1153 3.3.2011, 9:04

Цитата(Гость_Hepr_* @ 21.2.2011, 18:14) *
//! [0]
TimeEditDelegate::TimeEditDelegate(QObject *parent)
: QItemDelegate(parent)
{
}
//! [0]


кстати! А что вот эта штучка обозначает - "//! [0]" ? :)

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)