crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> QTableView для изменений, добавлений, удалений в базе данных
DenisKh001
  опции профиля:
сообщение 16.6.2011, 20:50
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 7
Регистрация: 16.6.2011
Пользователь №: 2752

Спасибо сказали: 0 раз(а)




Репутация:   0  


Есть QTableview и соединенная с ней QSqlTableModel (или QSQLRelationModel) - все работает, все обновляется. Есть ли готовое решение для добавления и удаления данных в базе так как это обычно делается - выделил строчку удалил, в конце таблицы фокус ввода прыгает не на первую строчку, а создается пустая запись. Или все это надо писать руками отлавливая сигналы? Тогда какой сигнал отлавливать на удаление строчки, а какой в момент перехода с последней строки QTableview?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
maint
  опции профиля:
сообщение 16.6.2011, 21:22
Сообщение #2


Участник
**

Группа: Участник
Сообщений: 235
Регистрация: 3.8.2009
Из: Иркутск
Пользователь №: 982

Спасибо сказали: 28 раз(а)




Репутация:   2  


Цитата(DenisKh001 @ 17.6.2011, 2:50) *
Есть QTableview и соединенная с ней QSqlTableModel (или QSQLRelationModel) - все работает, все обновляется. Есть ли готовое решение для добавления и удаления данных в базе так как это обычно делается - выделил строчку удалил, в конце таблицы фокус ввода прыгает не на первую строчку, а создается пустая запись. Или все это надо писать руками отлавливая сигналы? Тогда какой сигнал отлавливать на удаление строчки, а какой в момент перехода с последней строки QTableview?

я делал руками. По table->currentIndex вычислял текущую позицию. При удалении плясал от нее. Вставка - ухожу либо на конец, либо на начало, если сортировка по алфавиту
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
xzz
  опции профиля:
сообщение 15.6.2012, 10:34
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 15.6.2012
Пользователь №: 3422

Спасибо сказали: 0 раз(а)




Репутация:   0  


Господа здравствуйте!!у меня есть небольшая проблема....а именно:с qt совсем недавно...думаю как бы изменять,добавлять,удалять данные в приложении,бд в postgres.....начал писать...выдает такую ошибку...:
QSqlRelationalTableModel *objectRelation = new QSqlRelationalTableModel(0);
objectRelation->setTable("object");
objectRelation->setRelation(1, QSqlRelation("id_object","name"));
objectRelation->select();
objectRelation->setEditStradegy (QSqlTableModel::OnManualSubmit);

main.cpp(37) : error C2661: QSqlRelation::QSqlRelation: нет перегруженной функции, принимающей 2 аргументов
main.cpp(39) : error C2039: setEditStradegy: не является членом "QSqlRelationalTableModel"
и студия то русская((((
если есть примеры как проще можно сделать...очень буду благодарен!!
и если не сложно,небольшой примерчик толковый...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
maint
  опции профиля:
сообщение 15.6.2012, 10:48
Сообщение #4


Участник
**

Группа: Участник
Сообщений: 235
Регистрация: 3.8.2009
Из: Иркутск
Пользователь №: 982

Спасибо сказали: 28 раз(а)




Репутация:   2  


objectRelation->setRelation(1, QSqlRelation("id_object","name"));

синтаксическая ошибка в setRelation. Должно быть 3 аргумента. Таблица, индекс, поле.
Примерчик краткий и понятный есть в инсталляционном пакете. В example - relationtablemodel и masterdetail
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
xzz
  опции профиля:
сообщение 15.6.2012, 15:32
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 4
Регистрация: 15.6.2012
Пользователь №: 3422

Спасибо сказали: 0 раз(а)




Репутация:   0  


а на пальцах можно))?немного хотя бы....либо исходник маленького проекта.....в одну таблицу
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
maint
  опции профиля:
сообщение 15.6.2012, 15:47
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 235
Регистрация: 3.8.2009
Из: Иркутск
Пользователь №: 982

Спасибо сказали: 28 раз(а)




Репутация:   2  


Цитата(xzz @ 15.6.2012, 21:32) *
а на пальцах можно))?немного хотя бы....либо исходник маленького проекта.....в одну таблицу

я же писал, в одном пакете с Qt идут примеры. В Винде это папка example, так где установлено. В линухе в /usr/lib/qt4/example. Там ищем каталог sql.
в каталоге два подкаталога, где есть эти замечательные примеры. Называются masterdetail и relationtablemodel. Очень просто и доступно написано. Как раз для обучения

Сообщение отредактировал maint - 15.6.2012, 15:48
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
vankleef
  опции профиля:
сообщение 17.6.2012, 3:57
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 74
Регистрация: 21.10.2010
Пользователь №: 2134

Спасибо сказали: 9 раз(а)




Репутация:   1  


Цитата(xzz @ 15.6.2012, 16:32) *
а на пальцах можно))?немного хотя бы....либо исходник маленького проекта.....в одну таблицу


http://www.forum.crossplatform.ru/index.php?showtopic=6140
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Mingun
  опции профиля:
сообщение 11.7.2012, 6:37
Сообщение #8


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 28.9.2009
Пользователь №: 1122

Спасибо сказали: 0 раз(а)




Репутация:   0  


Вот как я решил исходную задачу автора темы. Здесь код на Java, на C++ переписать не состовит труда. Сделано с помощью специальной прокси-модели, добавляющей в конец одну строчку и при установке данных в нее добавляющей новую строчку в конец исходной модели, а затем делегирующей ей установку данных.
import com.trolltech.qt.core.QModelIndex;
import com.trolltech.qt.core.Qt;
import com.trolltech.qt.gui.QAbstractTableModel;

public class AutoAddProxyTableModel extends QAbstractTableModel {
    private QAbstractTableModel sourceModel;

    public AutoAddProxyTableModel() {
    }

    public AutoAddProxyTableModel(QAbstractTableModel sourceModel) {
        setSourceModel(sourceModel);
    }

    @Override
    public int rowCount(QModelIndex parent) {
        if (sourceModel == null)
            return 0;
        return sourceModel.rowCount(parent)+1;
    }

    @Override
    public int columnCount(QModelIndex parent) {
        if (sourceModel == null)
            return 0;
        return sourceModel.columnCount(parent);
    }

    @Override
    public Object data(QModelIndex index, int role) {
        if (sourceModel == null)
            return null;
        if (index == null)
            return sourceModel.data(index, role);
        if (isExtraRow(index)) {
            if (role == Qt.ItemDataRole.DisplayRole) {
                return tr("<enter value to add>");
            }
            return null;
        }
        return sourceModel.data(index, role);
    }

    @Override
    public Object headerData(int section, Qt.Orientation orientation, int role) {
        if (sourceModel == null)
            return super.headerData(section, orientation, role);
        return sourceModel.headerData(section, orientation, role);
    }

    /**
     * Если устанавливаются данные в последную ячейку, то в исходную таблицу
     * вставляется новая строка и эти данные заносятся в нее.
     * @param index
     * @param value
     * @param role
     * @return
     */
    @Override
    public boolean setData(QModelIndex index, Object value, int role) {
        if (sourceModel == null)
            return super.setData(index, value, role);
        if (index == null)
            return sourceModel.setData(index, value, role);
        if (isExtraRow(index)) {
            // Ключевой момент - при установке данных в дополнительную ячейку
            // создаем в исходной модели строку.
            beginInsertRows(null, index.row(), index.row());
            sourceModel.insertRow(index.row());
            endInsertRows();
        }
        return sourceModel.setData(index, value, role);
    }

    @Override
    public Qt.ItemFlags flags(QModelIndex index) {
        if (sourceModel == null)
            return Qt.ItemFlag.createQFlags();
        return sourceModel.flags(index);
    }

    public final void setSourceModel(QAbstractTableModel sourceModel) {
        this.sourceModel = sourceModel;
    }
    public final QAbstractTableModel sourceModel() {
        return this.sourceModel;
    }

    @Override
    public boolean removeRows(int row, int count, QModelIndex parent) {
        if (sourceModel == null)
            return false;
        // Убеждаемся, что наша строка не будет удалена.
        count = Math.min(row+count, sourceModel.rowCount()) - row;
        // Предыдущей операцией количество могло стать отрицательным
        if (count <= 0)
            return false;
        beginRemoveRows(parent, row, row+count-1);
        boolean result = sourceModel.removeRows(row, count, parent);
        endRemoveRows();

        return result;
    }

    @Override
    public boolean removeColumns(int row, int count, QModelIndex parent) {
        if (sourceModel == null)
            return false;
        return sourceModel.removeColumns(row, count, parent);
    }
    private boolean isExtraRow(QModelIndex index) {
        return index.row() == rowCount()-1;
    }
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Mingun
  опции профиля:
сообщение 22.10.2012, 11:18
Сообщение #9


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 28.9.2009
Пользователь №: 1122

Спасибо сказали: 0 раз(а)




Репутация:   0  


Вот окончательный вариант, в котором выправлены некоторые баги исходного.
import com.trolltech.qt.core.QModelIndex;
import com.trolltech.qt.core.Qt;
import com.trolltech.qt.gui.QAbstractTableModel;

/**
* Прокси-модель данных, позволяющая создавать строки путем редактирования последний
* специальный строки. Обратите внимание, что для древовидной модели сделать аналогичную
* прокси-модель будет сложнее, т.к. в таком случае нетривиально преобразование индексов.
* (Тем не менее, изменения нужны только в методах mapToSource и mapFromSource).
* Для табличной модели это преобразование можно вообще не делать, т.к. там имеет значение
* только числовые параметры, а на внутренние данные, асоциированные с каждым индексом,
* внимание не обращается. Но тем не менее лучшене рисковать - это не то место, где стоит
* оптимизировать :)
* @author Mingun
*/
public class AutoAddProxyTableModel extends QAbstractTableModel {
    private QAbstractTableModel sourceModel;
    private final Object specialValue = tr("<enter value to add>");

    public AutoAddProxyTableModel() {
    }

    public AutoAddProxyTableModel(QAbstractTableModel sourceModel) {
        setSourceModel(sourceModel);
    }
    //<editor-fold defaultstate="collapsed" desc="QAbstractItemModel">
    @Override
    public int rowCount(QModelIndex parent) {
        if (sourceModel == null)
            return 0;
        // Дополнительная строка, при редактировании которой добавляется новая
        // строка в исходную модель.
        return sourceModel.rowCount(mapToSource(parent))+1;
    }
    
    @Override
    public int columnCount(QModelIndex parent) {
        if (sourceModel == null)
            return 0;
        return sourceModel.columnCount(mapToSource(parent));
    }
    
    @Override
    public Object data(QModelIndex index, int role) {
        if (sourceModel == null)
            return null;
        if (isExtraRow(index)) {
            if (role == Qt.ItemDataRole.DisplayRole) {
                return specialValue;
            }
            return null;
        }
        return sourceModel.data(mapToSource(index), role);
    }
    
    @Override
    public Object headerData(int section, Qt.Orientation orientation, int role) {
        if (sourceModel == null)
            return super.headerData(section, orientation, role);
        return sourceModel.headerData(section, orientation, role);
    }
    
    /**
     * Если устанавливаются данные в последную ячейку, то в исходную таблицу
     * вставляется новая строка и эти данные заносятся в нее.
     * @param index
     * @param value
     * @param role
     * @return
     */
    @Override
    public boolean setData(QModelIndex index, Object value, int role) {
        if (sourceModel == null)
            return super.setData(index, value, role);
        if (isExtraRow(index)) {
            // Если вставить строку не удалось, сообщаем, что задать данные не
            // получилось.
            if (!sourceModel.insertRow(index.row())) {
                return false;
            }
        }
        return sourceModel.setData(mapToSource(index), value, role);
    }
    
    @Override
    public Qt.ItemFlags flags(QModelIndex index) {
        if (sourceModel == null)
            return Qt.ItemFlag.createQFlags();
        if (isExtraRow(index)) {
            return Qt.ItemFlag.createQFlags(
                Qt.ItemFlag.ItemIsEnabled,
                //Qt.ItemFlag.ItemIsSelectable,
                Qt.ItemFlag.ItemIsEditable
            );
        }
        return sourceModel.flags(mapToSource(index));
    }
    
    @Override
    public boolean removeRows(int row, int count, QModelIndex parent) {
        if (sourceModel == null)
            return false;
        // Убеждаемся, что наша строка не будет удалена.
        count = Math.min(row+count, sourceModel.rowCount()) - row;
        // Предыдущей операцией количество могло стать отрицательным
        if (count <= 0)
            return false;
        return sourceModel.removeRows(row, count, mapToSource(parent));
    }
    
    @Override
    public boolean removeColumns(int row, int count, QModelIndex parent) {
        if (sourceModel == null)
            return false;
        return sourceModel.removeColumns(row, count, mapToSource(parent));
    }
    //</editor-fold>

    public final void setSourceModel(QAbstractTableModel sourceModel) {
        // Эта функция появилась только в Qt 4.6 и вы должны использовать ее.
        // Если же у вас Qt 4,5, то используйте beginRemoveRows/endRemoveRows/beginInsertRows/endInsertRows,
        // как в коде ниже.
        //beginResetModel();
        if (this.sourceModel != null) {
            beginRemoveRows(null, 0, this.sourceModel.rowCount());
            this.sourceModel = null;
            endRemoveRows();

            disconnectSlots();
        }
        if (sourceModel != null) {
            beginInsertRows(null, 0, sourceModel.rowCount());
            this.sourceModel = sourceModel;
            endInsertRows();
            
            connectSlots();
        }
        // Эта функция появилась только в Qt 4.6 и вы должны использовать ее.
        // Если же у вас Qt 4,5, то используйте beginRemoveRows/endRemoveRows/beginInsertRows/endInsertRows,
        // как в коде выше.
        //endResetModel();
    }
    public final QAbstractTableModel sourceModel() {
        return this.sourceModel;
    }

    private boolean isExtraRow(QModelIndex index) {
        return index != null && index.row() == rowCount()-1;
    }
    
    private void connectSlots() {
        sourceModel.dataChanged.connect(this, "onSourceDataChanged(com.trolltech.qt.core.QModelIndex,com.trolltech.qt.core.QModelIndex)");
        sourceModel.headerDataChanged.connect(this, "onSourceHeaderDataChanged(com.trolltech.qt.core.Qt.Orientation,int,int)");

        sourceModel.rowsAboutToBeInserted.connect(this, "onSourceRowsAboutToBeInserted(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.rowsAboutToBeRemoved.connect(this, "onSourceRowsAboutToBeRemoved(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.rowsInserted.connect(this, "onSourceRowsInserted(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.rowsRemoved.connect(this, "onSourceRowsRemoved(com.trolltech.qt.core.QModelIndex,int,int)");

        sourceModel.columnsAboutToBeInserted.connect(this, "onSourceColumnsAboutToBeInserted(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.columnsAboutToBeRemoved.connect(this, "onSourceColumnsAboutToBeRemoved(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.columnsInserted.connect(this, "onSourceColumnsInserted(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.columnsRemoved.connect(this, "onSourceColumnsRemoved(com.trolltech.qt.core.QModelIndex,int,int)");

        sourceModel.layoutAboutToBeChanged.connect(this, "onSourceLayoutAboutToBeChanged()");
        sourceModel.layoutChanged.connect(this, "onSourceLayoutChanged()");
    }
    
    private void disconnectSlots() {
        sourceModel.dataChanged.disconnect(this, "onSourceDataChanged(com.trolltech.qt.core.QModelIndex,com.trolltech.qt.core.QModelIndex)");
        sourceModel.headerDataChanged.disconnect(this, "onSourceHeaderDataChanged(com.trolltech.qt.core.Qt.Orientation,int,int)");

        sourceModel.rowsAboutToBeInserted.disconnect(this, "onSourceRowsAboutToBeInserted(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.rowsAboutToBeRemoved.disconnect(this, "onSourceRowsAboutToBeRemoved(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.rowsInserted.disconnect(this, "onSourceRowsInserted(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.rowsRemoved.disconnect(this, "onSourceRowsRemoved(com.trolltech.qt.core.QModelIndex,int,int)");

        sourceModel.columnsAboutToBeInserted.disconnect(this, "onSourceColumnsAboutToBeInserted(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.columnsAboutToBeRemoved.disconnect(this, "onSourceColumnsAboutToBeRemoved(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.columnsInserted.disconnect(this, "onSourceColumnsInserted(com.trolltech.qt.core.QModelIndex,int,int)");
        sourceModel.columnsRemoved.disconnect(this, "onSourceColumnsRemoved(com.trolltech.qt.core.QModelIndex,int,int)");

        sourceModel.layoutAboutToBeChanged.disconnect(this, "onSourceLayoutAboutToBeChanged()");
        sourceModel.layoutChanged.disconnect(this, "onSourceLayoutChanged()");
    }

    private QModelIndex mapFromSource(QModelIndex sourceIndex) {
        if (sourceIndex == null) {
            return null;
        }
        return index(sourceIndex.row(), sourceIndex.column());
    }
    private QModelIndex mapToSource(QModelIndex proxyIndex) {
        if (proxyIndex == null) {
            return null;
        }
        return sourceModel.index(proxyIndex.row(), proxyIndex.column());
    }
    //<editor-fold defaultstate="collapsed" desc="Слоты">
    private void onSourceDataChanged(QModelIndex topLeft, QModelIndex bottomRight) {
        topLeft     = mapFromSource(topLeft);
        bottomRight = mapFromSource(bottomRight);
        dataChanged.emit(topLeft, bottomRight);
    }
    private void onSourceHeaderDataChanged(Qt.Orientation orientation, int first, int last) {
        headerDataChanged.emit(orientation, first, last);
    }
    
    private void onSourceRowsAboutToBeInserted(QModelIndex index, int start, int end) {
        index = mapFromSource(index);
        beginInsertRows(index, start, end);
    }
    private void onSourceRowsInserted(QModelIndex index, int start, int end) {
        endInsertRows();
    }
    private void onSourceRowsAboutToBeRemoved(QModelIndex index, int start, int end) {
        index = mapFromSource(index);
        beginRemoveRows(index, start, end);
    }
    private void onSourceRowsRemoved(QModelIndex index, int start, int end) {
        endRemoveRows();
    }
    
    private void onSourceColumnsAboutToBeInserted(QModelIndex index, int start, int end) {
        index = mapFromSource(index);
        beginInsertColumns(index, start, end);
    }
    private void onSourceColumnsInserted(QModelIndex index, int start, int end) {
        endInsertColumns();
    }
    private void onSourceColumnsAboutToBeRemoved(QModelIndex index, int start, int end) {
        index = mapFromSource(index);
        beginRemoveColumns(index, start, end);
    }
    private void onSourceColumnsRemoved(QModelIndex index, int start, int end) {
        endRemoveRows();
    }

    private void onSourceLayoutAboutToBeChanged() {
        layoutAboutToBeChanged.emit();
    }
    private void onSourceLayoutChanged() {
        layoutChanged.emit();
    }
    //</editor-fold>
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.11.2024, 2:38