Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Кнопка в QTableView


Автор: Sosed 5.8.2010, 17:14
Имеется делегат, с помошью которого устанавливаю в таблицу столбец QPushButton'ов.
Собственно нужно по нажатию одного из QPushButton'a вызвать диалог, после закрытия которого записать данные в ячейку с вызвавшей его кнопкой.
Проблема в том что я запутался в MVC и немогу понять куда воткнуть connect для кнопки. Если его делать в методе делегата createEditor, то как записать данные в модель, в нужное место? Есть мысль хранить указатель на модель в классе делегата и использовать сигналмапер для коннекта кнопок, передавая номер строки, на которой расположена кнопка, столбец "вшить", он не меняется, соответственно зная точные координаты ячейки записать данные проблемы не составит. 
Но что-то не нравится мне этот указатель в классе делегата да и попахивает это решение. Как правильно сделать?

Автор: icecrashldr 5.8.2010, 17:37
Забыл как в QT присваеваются ID к кнопкам..
Вообщем идея в том, что бы по ID кнопки можно было вычислить номер строки, тогда получится динамика. smile

Автор: Sosed 5.8.2010, 18:13
Класс делегата сейчас примерно такой
Код

class Delegate : public QItemDelegate {
    Q_OBJECT

public:
    Delegate(QObject* pobj) : QItemDelegate(pobj), model(0)
    {
        signalMapper = new QSignalMapper(this);
        connect(signalMapper, SIGNAL(mapped(int)),
                this, SLOT(openOptionDialog(int)));
        ...
    }

    QWidget *createEditor(QWidget *parent,
                          const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
    {
        if(index.column() == 4) {
            if(!model) model = index.model();
            QPushButton *pb = new QPushButton(parent);
            connect(pb, SIGNAL(clicked()), signalMapper, SLOT(map()));
            signalMapper->setMapping(pb, index.row());
            return pb;
        } else {
            return QItemDelegate::createEditor(parent, option, index);
        }
    }

  public slots:
    void openOptionDialog(int row) {
        OptionDialog od(model, row);
        od.exec();
    }

private:
    QSignalMapper *signalMapper;
    QAbstractItemModel *model;
};

Такое чувство что все эти манипуляции нужно делать где-то в другом месте.

Цитата

Забыл как в QT присваеваются ID к кнопкам..

да вроде никак) У меня проблему вычисления строки решает сигналмапер.

Автор: icecrashldr 6.8.2010, 10:39
Идея в том что бы для всех buttons поставить один слот, а в слоту разберать на какой button был клик. Либо можно пронаследоваться от QPushButton и добавить свои уникальные данные.

Автор: borisbn 6.8.2010, 12:38
Цитата(icecrashldr @  6.8.2010,  10:39 Найти цитируемый пост)
Либо можно пронаследоваться от QPushButton и добавить свои уникальные данные.

Наследоваться необязательно. Каждому объекту, наследованного от QObject, можно задать свойство типа так:
Код

btn->setProperty( "index", idx );

а в слоте вычитывать её
Код

void ObjName::onButton()
{
    int idx = sender()->property( "index" ).toInt();
}

Автор: icecrashldr 6.8.2010, 12:44
borisbn, Точно, точно smile

Автор: Sosed 6.8.2010, 18:34
С индексами разобрались а как данные то записать?
С if(!model) model = index.model(); я немного опечатался, метод то const, да и вообще правильно ли хранить указатель на модель в делегате? Кнопка отображается с помощью openPersistentEditor, поэтому немогу засунуть код слота openOptionDialog в метод делегата setModelData, диалог появляется не сразу, а после щелчка на другой ячейке(

Автор: Sosed 7.8.2010, 16:31
Скривившись сделал так
Код

void Delegate::openOptionDialog() {
    int row = sender()->property("row").toInt();
    int column = sender()->property("column").toInt();
    QTableView *tableView = qobject_cast<QTableView*>(sender()->parent()->parent());
    QAbstractItemModel *model = tableView->model();

    QString settings = model->index(row, column).data().toString();
    OptionDialog dialog(settings);
    if( dialog.exec() ) { //ok
        QVariant value(dialog.getSettings());
        model->setData(model->index(row, column), value, Qt::EditRole);
    }
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)