Russian Qt Forum
Ноябрь 01, 2024, 09:40 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с ЛистВью и делегатами  (Прочитано 4316 раз)
qt_newer
Гость
« : Январь 19, 2015, 19:17 »

Есть список (id, name получаемый из базы данных), по нажатию на элемент которого должно открываться диалоговое окно с вопросом удалить ли текущую строку, если да, то в записи с соответствующим id изменяется поле deleted, и она перестает отображаться в списке.
Я могу передать index спп слоту, но не знаю, как передать  id. После апдейта таблицы есть 2 возможности: обновить модель в спп- в ContextProperty (что я сейчас делаю), либо убрать тек. запись внутри qml.
Таким образом, у меня 2 вопроса:
1) как удалить запись из модели внутри qml?
2) как получить id текущей записи в диалоговом окне?
Пример ниже: Непонимающий
ListView {
     id: mylist
     model: mymodel
     delegate:
         Rectangle
         {
                 Text {
                     text: id + '  ' +name
                 }
         }
         ...
         MouseArea
         {
             anchors.fill: parent
             onClicked:
             {
                 mylist.currentIndex = index;
                 mydialog.popupVisible = true

             }
         }
}
CustomDialog {

    id: mydialog
    popupVisible: false
    
    
    Button {
        ...
        onClicked: {
            mydialog.popupVisible = false
            // call cpp slot with id as parameter
        }
    }    
}
« Последнее редактирование: Январь 19, 2015, 22:47 от qt_newer » Записан
carrygun
Гость
« Ответ #1 : Январь 20, 2015, 05:24 »

mylist.model.get(mylist.currentIndex).id
Записан
qt_newer
Гость
« Ответ #2 : Январь 20, 2015, 12:55 »

Спасибо, но у меня модель наследуется от QSqlQueryModel и там нет метода get(), т.е. при попытке использовать mylist.model.get(mylist.currentIndex).id, получаю "Property 'get' of object is not a function"

В спп такой код выдает корректный ответ:
QModelIndex ind = mymodel.index(1, 0,QModelIndex());
qDebug() << "just test ID: " << mymodel.data(ind, Qt::UserRole).toInt();

Но использовать его в qml пока не получается:
console.log("current ID: " + mylist.model.data(mylist.currentIndex, mylist.model.UserRole )) выдает current ID: undefined

Вероятно, что-то не так с ролью, либо с определением модели:

class myModel : public QSqlQueryModel
{
    Q_OBJECT
public:
    myModel(QObject* parent = 0)
        : QSqlQueryModel(parent)
    {
        roleNamesHash.insert(Qt::UserRole,      QByteArray("id"));
        roleNamesHash.insert(Qt::UserRole + 1,  QByteArray("name"));
    }

    Q_INVOKABLE QVariant data(const QModelIndex& index, int role) const
    {
        if(role < Qt::UserRole) {
            return QSqlQueryModel::data(index, role);
        }

        QSqlRecord r = record(index.row());
        return r.value(role - Qt::UserRole);
    }

    QHash<int, QByteArray> roleNames() const { return roleNamesHash; }



private:
    QHash<int, QByteArray> roleNamesHash;
};

Если я дополнительно определяю в модели:
    Q_INVOKABLE QVariant get(const QModelIndex& index) const
    {
        QSqlRecord r = record(index.row());
        return r.value(0);
    }
то это опять работает в спп:
    qDebug() << "2nd test ID: " << mymodel.get(ind).toInt();
и не работает в qml:
console.log( "2nd test ID:" + mylist.model.get(mylist.currentIndex)) - возвращает 0


PS Код должен работать в Qt 5.0
« Последнее редактирование: Январь 20, 2015, 13:02 от qt_newer » Записан
carrygun
Гость
« Ответ #3 : Январь 20, 2015, 13:07 »

У вас функция ожидает QModelIndex, а вы передаете int.
Записан
qt_newer
Гость
« Ответ #4 : Январь 20, 2015, 13:17 »

да, похоже на то В замешательстве
Я передаю mylist.currentIndex, а как передавать индекс модели ?

ListView {
     id: mylist
     model: mymodel
     delegate:
         ...
         MouseArea
         {
             anchors.fill: parent
             onClicked:
             {
                 mylist.currentIndex = index;
                 mydialog.popupVisible = true

             }
         }
}
Записан
qt_newer
Гость
« Ответ #5 : Январь 20, 2015, 13:31 »

PS получилось только в спп функцию get() переделать, чтобы она int принимала, тогда все работает
Записан
qt_newer
Гость
« Ответ #6 : Январь 20, 2015, 19:53 »

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

    QSqlQuery q;
    QString s= "UPDATE mytable SET deleted = 1 WHERE id ="+ id;
    if (!q.exec(s))
        qDebug() << q.lastError() << "in " << s;

    myModel mymodel;
    mymodel.setQuery("select * from mytable where deleted=0);

    view->rootContext()->setContextProperty("mymodel", &mymodel);

то это даже срабатывает для первой удаленной записи, но при попытке удалить еще одну- приложение вылетает

Также я пробую вместо обновления контекста сделать рефреш модели:
        QModelIndex ind = this->index(0, 0,QModelIndex());
        QModelIndex ind2 = this->index(rowCount()-1, columnCount()-1,QModelIndex());

        QVector<int> v;

        v << Qt::UserRole << Qt::UserRole + 1 << Qt::UserRole + 2 ...
        emit dataChanged(ind, ind2, v);

но в этом случае записи c делетед = 1 продолжают отображаться в листвью.

Заранее спасибо за любые советы!
« Последнее редактирование: Январь 20, 2015, 20:00 от qt_newer » Записан
qt_newer
Гость
« Ответ #7 : Январь 22, 2015, 11:28 »

Удалось разобраться самостоятельно, проблема была в том, что при начальной установке и в спп слоте использовались разные объекты модели- введение синглтона решило проблему, и стало достаточно использовать в слоте:
    myModel *myModel = myModel::getInstance();
    myModel->setQuery(sql);
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.094 секунд. Запросов: 20.