Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Денис от Октябрь 08, 2014, 14:38



Название: Новая проблема QHeaderView наследование и слоты
Отправлено: Денис от Октябрь 08, 2014, 14:38
В очередной раз обращаюсь к сообществу ... Создал таблицу основную на QAbstractTableModel ...
А теперь пытаюсь создать на основе этой модели таблицу с редактируемыми данными, но ничего не получается, не могу найти и переопределить слот изменения объекта, а также на работает выдача объектов в виде QTableWidgetItem ?

Код:
bool BaseClientTable::setData(int row, int column, QTableWidgetItem &item)
{
    array[BaseClientTable::column * row + column] = item;
}

QVariant BaseClientTable::data(const QModelIndex& index, int role) const
{
    if(role == HierarchicalHeaderView::HorizontalHeaderDataRole)
    {
        QVariant var;
        var.setValue((QObject*)&horizontalHeaderModel);
        return var;
    }
    if(role == HierarchicalHeaderView::VerticalHeaderDataRole)
    {
        QVariant var;
        var.setValue((QObject*)&verticalHeaderModel);
        return var;
    }
    if(role == Qt::DisplayRole && index.isValid())
    {
        return array[BaseClientTable::column*index.row() + index.column()];
    }
    return QVariant();
}

Выдает ошибку:
ошибка: could not convert '*(((QTableWidgetItem*)((const BaseClientTable*)this)->BaseClientTable::array) + ((sizetype)(((unsigned int)((((int)((const BaseClientTable*)this)->BaseClientTable::column) * (& index)->QModelIndex::row()) + (& index)->QModelIndex::column())) * 24u)))' from 'QTableWidgetItem' to 'QVariant'
         return array[BaseClientTable::column*index.row() + index.column()];


 Если же в качестве объекта выдавать QString, то все работает, так как QVariant может хранить данный класс, а вот конвертация в QTableWidgetItem невозможна (


Название: Re: QAbstractTableModel наследование и слоты
Отправлено: gil9red от Октябрь 08, 2014, 15:19
Потому что, объект QTableWidgetItem работает только с QTableWidget и наоборот.
Для QAbstractTableModel вам придется самому добавить методы для работы с QTableWidgetItem.


Название: Re: QAbstractTableModel наследование и слоты
Отправлено: Денис от Октябрь 08, 2014, 15:23
Ну хорошо, а как тогда в моей модели таблицы сделать чтобы ячейка была редактируемой ? Есть пример ?
Данные таблицы для отображения выдает эта функция data(...), а она определена только так, я могу конечно возвращать текст объекта QTableWidgetItem, то как мне сделать чтобы приходило событие ио двойном щелчке и ячейка становилась редактируемой ?


Название: Re: QAbstractTableModel наследование и слоты
Отправлено: Денис от Октябрь 08, 2014, 16:30
Подсмотрел пример http://asinenko.com/qabstractitemmodel-rtti/

И получил такой код:
Код:
class BaseClientTable: public QAbstractTableModel
{
    Q_OBJECT

public:
    BaseClientTable(int row, int column, int language, QObject* parent = 0);

    int rowCount(const QModelIndex& /*parent*/) const;
    int columnCount(const QModelIndex& /*parent*/) const;

    QVariant data(const QModelIndex& index, int role) const;
    bool setData(int row, int column, QString item);
    void changeHeader(unsigned short);

private:
    QStandardItemModel horizontalHeaderModel;
    QStandardItemModel verticalHeaderModel;

    QString *str;
    int row;
    int column;
    int language;

    void init();
    void fillHeaderHorizontal(QStandardItemModel& headerModel);
};

class BaseClientDelegate : public QItemDelegate
{
public:
    BaseClientDelegate();
    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;
};

Далее сделал так:
Код:
    ui->tableView->setItemDelegate(new BaseClientDelegate);
    ui->tableView->setModel(baseClient);
    ui->tableView->show();

Но связывания не произошло и не вызываются редакторы виджетов, может необходимо connect где-то сделать ?


Название: Re: QAbstractTableModel наследование и слоты
Отправлено: Fregloin от Октябрь 08, 2014, 17:17
Советую почитать документацию про модели и делегаты. Есть в разных учебниках по Qt на русском. Сразу станет все понятно.
Потратьте пару часов.


Название: Re: QAbstractTableModel наследование и слоты
Отправлено: Денис от Октябрь 08, 2014, 22:52
Хорошо, с этим как-то разобрался, но появилась новая проблема:
Код:
    QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"),QDir::currentPath(),"Text File (*.csv)");

    if(QFile(fileName).exists())
    {
        ui->tableClient->close();
        baseClient->openFile(fileName);
        ui->tableClient->show();
    }
    else
        QMessageBox::information(this,tr("Ошибка"),"Файла не существует, проверьте имя файла !");
baseClient - это модель таблицы, там определена функция открытия файла, но вот незадача ... после обновления количества строк до меньшего, у меня остаются лишние строки
Как бы мне сообщить tableClient-QTableView что количество строк уменьшилось, чтобы он перерисовал табличку 7


Название: Re: QAbstractTableModel наследование и слоты
Отправлено: Wulff007 от Октябрь 09, 2014, 12:11
Покажи весь код, по хидеру ничего не определишь. Что бы сделать редактируемые ячейки нужно переопределить у модели flags(читай доки по QAbstractItemModel)


Название: Re: QAbstractTableModel наследование и слоты
Отправлено: Денис от Октябрь 09, 2014, 23:33
Покажи весь код, по хидеру ничего не определишь. Что бы сделать редактируемые ячейки нужно переопределить у модели flags(читай доки по QAbstractItemModel)

Разобрался уже, после редактирования количеста строк необходимо было испустить сигнал:
Код:
emit layoutChanged();

Он ловится QTableView и он запрашивает новое количествог строк у модели и перерисовывается по ним ...


Название: Re: QAbstractTableModel наследование и слоты [РЕШЕНО]
Отправлено: Денис от Октябрь 10, 2014, 21:00
Возник новый вопрос по таблице, а как сделать что бы выделялся заголовок столбцов, то есть по нему щелкаещь а он выделяется, из-за этого у меня не делается сортировка ?


Название: Re: QAbstractTableModel наследование и слоты
Отправлено: Денис от Октябрь 10, 2014, 21:13
Так с этим опять разобрался, не включалась так как я включил сортировку, но ее нужно же как-то определять ?


Название: Re: QAbstractTableModel наследование и слоты
Отправлено: Денис от Октябрь 10, 2014, 22:18
С сортировкой разобрался включив посредника QSortFilterProxyModel, и она происходит но есть проблема, не отображаются стрелки сортировки ? и посредник оставляет нумерацию строк в результате получается следующее:

(http://i65.fastpic.ru/thumb/2014/1010/e2/216b8caf123b71efcff948b070ef0ae2.jpeg) (http://fastpic.ru/view/65/2014/1010/216b8caf123b71efcff948b070ef0ae2.png.html)

Как это побороть без отключения отображения нумерации строк ?


Название: Re: Новая проблема QAbstractTableModel наследование и слоты
Отправлено: Денис от Октябрь 11, 2014, 13:57
Кажется понял у меня используется иерархическая модель ходера, и видимо он по сигналу не перерисовывает заголовок колонки и не отображает стрелку, как бы мне перехватить и отрисоавть заголовок самому ?


Название: Re: Новая проблема QHeaderView наследование и слоты
Отправлено: Денис от Октябрь 11, 2014, 14:54
Ладно, расширю описание проблемы ... Проблема в следующем:
Прикрутил к QTableView иерархический хидер, а также с помощью класса QSortFilterProxyModel промежуточной модели организовал сортировку:
Код:
    proxyModel.setSourceModel(baseClient);
    ui->tableClient->setItemDelegate(new BaseClientDelegate);
    ui->tableClient->setModel(&proxyModel);

, но проблема в том что сортировка то происходит но не отображаются стрелки сортировки:

(http://i65.fastpic.ru/thumb/2014/1011/18/f4fd4c5e6210417bdd30ea0017ca5518.jpeg) (http://fastpic.ru/view/65/2014/1011/f4fd4c5e6210417bdd30ea0017ca5518.png.html)

и почему-то перепутана нумерация строк, я так понимаю в последнем щалит промежуточная модель QSortFilterProxyModel ?
А вот с первым уже замучался, включил отображение сортировки где только возможно но стрелки сортировки так и не появились ? Делал включение в QHeaderView:
Код:
hierarHeader->setSortIndicatorShown(true);

, также включал в таблице:
Код:
ui->tableClient->setSortingEnabled(true);
но отображения стрелок в таблице не происходит, может модель прорисовки необходимо описать или укажите плз в каком направлении копать ?


Название: Re: Новая проблема QHeaderView наследование и слоты
Отправлено: kambala от Октябрь 11, 2014, 19:49
проблема явно в кастомном иерархическом компоненте, покопайся в его исходниках

а номера видимо отсортировались вместе с данными :)


Название: Re: Новая проблема QHeaderView наследование и слоты
Отправлено: Денис от Октябрь 11, 2014, 20:10
проблема явно в кастомном иерархическом компоненте, покопайся в его исходниках

а номера видимо отсортировались вместе с данными :)

Уже покопался, там почемуто не обрабатывалось событие sortIndicatorChanged(int,Qt::SortOrder). Добавил вот такой кусок, работает но почемуто появляются стрелки для всех колонок, ходя в дебаге явно виден индекс нужной колонки :

Код:
HierarchicalHeaderView::HierarchicalHeaderView(Qt::Orientation orientation, QWidget *parent)
    :QHeaderView(orientation, parent), _pd(new private_data())
{
    connect(this, SIGNAL(sectionResized(int, int, int)), this, SLOT(on_sectionResized(int)));
    connect(this, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(on_sortIndicatorChanged(int, Qt::SortOrder)));
}

HierarchicalHeaderView::~HierarchicalHeaderView()
{
    delete _pd;
}

void HierarchicalHeaderView::on_sortIndicatorChanged(int logicalIndex, Qt::SortOrder state)
{
    if(state)
        sorrt = SortUp;
    else
        sorrt = SortDown;

    paintSection(new QPainter(), this->rect(), logicalIndex);
}

Продолжаю копать ...