Виталий Антипов21 февраля 2017 г. 2:00
ReferenceError: listModel is not defined
Здравствуйте! Прошу вашей помощи. Задача - отобразить в Draver список из базы sqlite, выполнить фильтрацию и передать указанный в списке элемент в Label, находящийся в ApplicationWindow. На основе ваших уроков написан такой код:
main.qml
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import QtQuick.Window 2.2 ApplicationWindow { id: window visible: true width: 1024 height: 768 objectName: "window" signal qmlSignal2() Button { id: badbut visible: false width: 100 height: 100 onClicked: qmlSignal() } Text { id: textfield2 objectName: "textfield2" visible: false } ToolBar { id: toolbar height: 40 anchors.top: window.top anchors.topMargin: 0 anchors.left: window.left anchors.leftMargin: 0 anchors.right: window.right anchors.rightMargin: 0 width: window.width Button { id: buttonpoisk highlighted: true width: parent.width/6 anchors.top: parent.top anchors.topMargin: 0 anchors.left: parent.left anchors.leftMargin: 0 anchors.bottom: parent.bottom anchors.bottomMargin: 0 onClicked: drawer.open() Text { id: textpoisk text: qsTr("Поиск") font.family: "Arial" font.bold: true color: "white" font.pixelSize: 20 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } } Pane { id: pane width: parent.width*4/6 anchors.top: parent.top anchors.topMargin: 0 anchors.left: buttonpoisk.right anchors.leftMargin: 0 anchors.bottom: parent.bottom anchors.bottomMargin: 0 background: Rectangle { color: "#353637" } Text { id: textpane text: qsTr("Калькулятор") font.family: "Arial" font.bold: true color: "white" font.pixelSize: 20 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } } Button { id: buttonmenu highlighted: true width: parent.width/6 anchors.top: parent.top anchors.topMargin: 0 anchors.left: pane.right anchors.leftMargin: 0 anchors.bottom: parent.bottom anchors.bottomMargin: 0 Text { id: textmenu text: qsTr("Меню") font.family: "Arial" font.bold: true color: "white" font.pixelSize: 20 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } } } Drawer { id: drawer width: window.width/3 height: window.height objectName: "drawer" Row { id: rowpoisk anchors.left: parent.left anchors.leftMargin: 5 anchors.right: parent.right anchors.rightMargin: 5 anchors.top: parent.top anchors.topMargin: 5 height: 40 spacing: 5 TextField { id: textfield1 objectName: "textfield1" width: 200 placeholderText: "Обозначение" font.pixelSize: 20 } Button { id: buttonp width: drawer.width - textfield1.width - 15 highlighted: true onClicked: { textfield2.text = textfield1.text; qmlSignal2() } Text { id: name1 text: qsTr("Поиск") font.family: "Arial" font.bold: true color: "white" font.pixelSize: 20 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } } } Flickable { id: view objectName: "view" width: parent.width anchors.top: rowpoisk.bottom anchors.topMargin: 5 anchors.bottom: parent.bottom contentWidth: parent.width transitions: Transition { NumberAnimation { properties: "opacity"; duration: 400 } } ListView { id: listpoisk objectName: "listpoisk" model: listModel anchors.fill: parent clip: true delegate: component headerPositioning: ListView.OverlayHeader spacing: 1 highlight: Rectangle { id: svet y: listpoisk.currentItem.y; Behavior on y { SpringAnimation { spring: 2; damping: 0.1 } } color: "#1E90FF" } highlightFollowsCurrentItem: true highlightMoveDuration : 100 } Component { id: component RowLayout { id: row property int number: index width: ListView.view.width height: 40 property var view: ListView.view property var isCurrent: ListView.isCurrentItem Rectangle { id: recbaza MouseArea { id: mouse anchors.fill: parent onClicked: { view.currentIndex = model.index window.editEntry(listpoisk.currentIndex) } } width: parent.width height: 40 color: "transparent" border.color: "#353637" Text { id: oboznachenie anchors.centerIn: parent font.pixelSize: 20 text: Oboznachenie + " (аналог " + OboznachenieEN + ")" } Text { id: text1 font.pixelSize: 10 text: listpoisk.currentIndex } } } } } } Label { id: text2 x: 387 y: 109 width: 243 height: 63 text: "test" font.pixelSize: 12 } Label { id: label x: 387 y: 187 width: 243 height: 63 text: listpoisk.currentIndex } function editEntry(row) { mapper.updateData(listpoisk.currentIndex) } Component.onCompleted: { mapper.addMapping(text2, (0x0100 + 2), "text") } }
database.h
#ifndef DATABASE_H #define DATABASE_H #include <QObject> #include <QtSql/QSqlDatabase> #include <QtSql/QSqlQuery> #include <QFile> #include <QDebug> #include <QSqlError> #define DATABASE_NAME "sqlite.db" #define BAZAPODSH "BazaPodsh" #define BAZAPODSH_OBOZNACHENIE "Oboznachenie" #define BAZAPODSH_OBOZNACHENIEEN "OboznachenieEN" #define BAZAPODSH_DVNUTR "dvnutr" #define BAZAPODSH_DNARUZH "Dnaruzh" #define BAZAPODSH_DTK "dtk" #define BAZAPODSH_ZTK "ztk" #define BAZAPODSH_UGOL "Ugol" class DataBase : public QObject { Q_OBJECT public: explicit DataBase(QObject *parent = 0); ~DataBase(); void connectToDataBase(); private: QSqlDatabase db; private: bool openDataBase(); bool restoreDataBase(); void closeDataBase(); bool creatTable(); signals: public slots: bool insertIntoTable(const QVariantList &data); bool insertIntoTable(const QString &Oboznachenie, const QString &OboznachenieEN, const QString &dvnutr, const QString &Dnaruzh, const QString &dtk, const QString &ztk, const QString &Ugol ); bool removeRecord(const int id); }; #endif
database.cpp
#include "database.h" DataBase::DataBase(QObject *parent) : QObject(parent) { } DataBase::~DataBase() { } void DataBase::connectToDataBase() { if(!QFile("D:/Projects/CalculatorBearingFrequencies2/" DATABASE_NAME).exists()) { this->restoreDataBase(); } else { this->openDataBase(); } } bool DataBase::restoreDataBase() { if(this->openDataBase()) { return true;// (this->creatTable()) ? true : false; } else { qDebug()<<"Не удалось восстановить базу данных"; return false; } return false; } bool DataBase::openDataBase() { db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("D:/Projects/CalculatorBearingFrequencies2/" DATABASE_NAME); if(db.open()) { return true; } else { return false; } } void DataBase::closeDataBase() { db.close(); } bool DataBase::creatTable() { QSqlQuery query; if(!query.exec( "CREATE TABLE " BAZAPODSH " (id INTEGER PRIMARY KEY ASC AUTOINCREMENT, " BAZAPODSH_OBOZNACHENIE " TEXT," BAZAPODSH_OBOZNACHENIEEN " TEXT," BAZAPODSH_DVNUTR " REAL," BAZAPODSH_DNARUZH " REAL," BAZAPODSH_DTK " REAL," BAZAPODSH_ZTK " REAL," BAZAPODSH_UGOL " REAL" ")" )) { qDebug()<<"Ошибка при создании базы"; qDebug() << query.lastError().text(); return false; } else { return true; } return false; } bool DataBase::insertIntoTable(const QVariantList &data) { QSqlQuery query; query.prepare("INSERT INTO " BAZAPODSH " ( " BAZAPODSH_OBOZNACHENIE ", " BAZAPODSH_OBOZNACHENIEEN ", " BAZAPODSH_DVNUTR ", " BAZAPODSH_DNARUZH ", " BAZAPODSH_DTK ", " BAZAPODSH_ZTK ", " BAZAPODSH_UGOL " ) " "VALUES (:Oboznachenie, :OboznachenieEN, :dvnutr, :Dnaruzh," ":dtk, :ztk, :Ugol)"); query.bindValue(":Oboznachenie", data[0].toString()); query.bindValue(":OboznachenieEN", data[1].toString()); query.bindValue(":dvnutr", data[2].toString()); query.bindValue(":Dnaruzh", data[3].toString()); query.bindValue(":dtk", data[4].toString()); query.bindValue(":ztk", data[5].toString()); query.bindValue(":Ugol", data[6].toString()); if(!query.exec()) { qDebug() << "Ошибка добавления записи " << BAZAPODSH; qDebug() << query.lastError().text(); return false; } else { return true; } return false; } bool DataBase::insertIntoTable(const QString &Oboznachenie, const QString &OboznachenieEN, const QString &dvnutr, const QString &Dnaruzh, const QString &dtk, const QString &ztk, const QString &Ugol) { QVariantList data; data.append(Oboznachenie); data.append(OboznachenieEN); data.append(dvnutr); data.append(Dnaruzh); data.append(dtk); data.append(ztk); data.append(Ugol); if(insertIntoTable(data)) return true; else return false; } bool DataBase::removeRecord(const int id) { QSqlQuery query; query.prepare(" DELETE FROM " BAZAPODSH " WHERE id = :ID ;"); query.bindValue(":ID", id); if(!query.exec()) { qDebug() << "Ошибка удаления записи " << BAZAPODSH; qDebug() << query.lastError().text(); return false; } else { return true; } return false; }
querymodel1.h
#ifndef QUERYMODEL1_H #define QUERYMODEL1_H #include <QObject> #include <QSqlQueryModel> class ListModel : public QSqlQueryModel { Q_OBJECT public: enum Roles { IdRole = Qt::UserRole + 1, BazaPodshOboznachenieRole, BazaPodshOboznachenieENRole, BazaPodshDvnutrRole, BazaPodshDnaruzhRole, BazaPodshDtkRole, BazaPodshZtkRole, BazaPodshUgolRole }; explicit ListModel(QObject *parent = 0); QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; protected: QHash<int, QByteArray> roleNames() const; signals: public slots: void updateModel(); int getId(int row); }; #endif
querymodel1.cpp
#include "querymodel1.h" #include <QDebug> #include "database.h" class poisk; ListModel::ListModel(QObject *parent) : QSqlQueryModel(parent) { this->updateModel(); } QVariant ListModel::data(const QModelIndex & index, int role) const { int columnId = role - Qt::UserRole - 1; QModelIndex modelIndex = this->index(index.row(), columnId); return QSqlQueryModel::data(modelIndex, Qt::DisplayRole); } QHash<int, QByteArray> ListModel::roleNames() const { QHash<int, QByteArray> roles; roles[IdRole] = "id"; roles[BazaPodshOboznachenieRole] = "Oboznachenie"; roles[BazaPodshOboznachenieENRole] = "OboznachenieEN"; roles[BazaPodshDvnutrRole] = "dvnutr"; roles[BazaPodshDnaruzhRole] = "Dnaruzh"; roles[BazaPodshDtkRole] = "dtk"; roles[BazaPodshZtkRole] = "ztk"; roles[BazaPodshUgolRole] = "Ugol"; return roles; } void ListModel::updateModel() { QString str; QObject* textfield2 = this->parent()->findChild<QObject*>("textfield2"); str=(textfield2->property("text")).toString(); qDebug()<<"в запросе model"<< str; this->setQuery("SELECT id, " BAZAPODSH_OBOZNACHENIE ", " BAZAPODSH_OBOZNACHENIEEN ", " BAZAPODSH_DVNUTR ", " BAZAPODSH_DNARUZH ", " BAZAPODSH_DTK ", " BAZAPODSH_ZTK ", " BAZAPODSH_UGOL " FROM " BAZAPODSH " WHERE " BAZAPODSH_OBOZNACHENIE " LIKE '%"+str+"%' OR " BAZAPODSH_OBOZNACHENIEEN " LIKE '%"+str+"%' "); } int ListModel::getId(int row) { return this->data(this->index(row, 0), IdRole).toInt(); }
datamapper1.h (взят из уроков без изменений)
#ifndef DATAMAPPER1_H #define DATAMAPPER1_H #include <QObject> #include <QPointer> #include <QAbstractItemModel> #include <QModelIndex> #include <QQuickItem> class DataMapper1Private; class DataMapper1 : public QObject { Q_OBJECT Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) Q_PROPERTY(int count READ count NOTIFY countChanged) public: explicit DataMapper1(QObject *parent = 0); ~DataMapper1(); void clearMapping(); void removeMapping(QObject *object); int currentIndex() const; int count() const; QByteArray mappedPropertyName(QObject *object) const; int mappedSection(QObject *object) const; QObject * mappedControlAt(const int §ion) const; QAbstractItemModel * model() const; void setModel(QAbstractItemModel *model); public Q_SLOTS: void addMapping(QObject *object, const int §ion); void addMapping(QObject *object, const int §ion, const QByteArray &propertyName); void revert(); void setCurrentIndex(int index); void toFirst(); void toLast(); void toNext(); void toPrevious(); void updateData(int index); public slots: Q_SIGNALS: void currentIndexChanged(int index); void countChanged(); private: DataMapper1Private * const d; }; #endif
datamapper1.cpp (взят из уроков без изменений)
#include "datamapper1.h" struct Mapping { QPointer <QObject> object; int section; QByteArray propertyName; }; class DataMapper1Private { public: DataMapper1Private() : m_model(0), m_currentIndex(-1) { } void updateMapping(Mapping &mapping, QObject *object, const int §ion, const QByteArray &propertyName); void update(); QAbstractItemModel* m_model; QVector<Mapping> m_mappings; int m_currentIndex; }; void DataMapper1Private::updateMapping(Mapping &mapping, QObject *object, const int §ion, const QByteArray &propertyName) { mapping.object = object; mapping.section = section; mapping.propertyName = (propertyName.isEmpty() ? "text" : propertyName); } void DataMapper1Private::update() { if (!m_model) return; if (m_mappings.isEmpty()) return; if (m_currentIndex == -1) return; foreach (const Mapping &mapping, m_mappings) { if (mapping.object) { mapping.object->setProperty(mapping.propertyName, m_model->data(m_model->index(m_currentIndex,0), mapping.section)); } } } DataMapper1::DataMapper1(QObject *parent) : QObject(parent), d(new DataMapper1Private()) { } DataMapper1::~DataMapper1() { delete d; } void DataMapper1::addMapping(QObject *object, const int §ion) { addMapping(object, section, "text"); } void DataMapper1::addMapping(QObject *object, const int §ion, const QByteArray &propertyName) { for (int i = 0; i < d->m_mappings.count(); ++i) { Mapping &mapping = d->m_mappings[i]; if (mapping.object == object) { d->updateMapping(mapping, object, section, propertyName); d->update(); return; } } Mapping mapping; d->updateMapping(mapping, object, section, propertyName); d->m_mappings.append(mapping); d->update(); } void DataMapper1::clearMapping() { d->m_mappings.clear(); } int DataMapper1::currentIndex() const { return d->m_currentIndex; } int DataMapper1::count() const { if (!d->m_model) return 0; return d->m_model->rowCount(); } QByteArray DataMapper1::mappedPropertyName(QObject *object) const { foreach(const Mapping &mapping, d->m_mappings) { if (mapping.object == object) return mapping.propertyName; } return QByteArray(); } int DataMapper1::mappedSection(QObject *object) const { foreach(const Mapping &mapping, d->m_mappings) { if (mapping.object == object) return mapping.section; } return 0; } QObject* DataMapper1::mappedControlAt(const int §ion) const { foreach(const Mapping &mapping, d->m_mappings) { if (mapping.section == section) return mapping.object; } return 0; } QAbstractItemModel* DataMapper1::model() const { return d->m_model; } void DataMapper1::removeMapping(QObject *object) { for (int i = 0; i < d->m_mappings.count(); ++i) { if (d->m_mappings[i].object == object) { d->m_mappings.remove(i); return; } } } void DataMapper1::setModel(QAbstractItemModel *model) { d->m_model = model; d->m_currentIndex = 0; d->update(); emit countChanged(); } void DataMapper1::revert() { d->update(); } void DataMapper1::setCurrentIndex(int index) { if (!d->m_model) return; const int rowCount = d->m_model->rowCount(); if (index < 0 || index >= rowCount) return; d->m_currentIndex = index; d->update(); emit currentIndexChanged(d->m_currentIndex); } void DataMapper1::toFirst() { setCurrentIndex(0); } void DataMapper1::toLast() { if (!d->m_model) return; const int rowCount = d->m_model->rowCount(); setCurrentIndex(rowCount - 1); } void DataMapper1::toNext() { setCurrentIndex(d->m_currentIndex + 1); } void DataMapper1::toPrevious() { setCurrentIndex(d->m_currentIndex - 1); } void DataMapper1::updateData(int index) { d->m_currentIndex = index; d->update(); emit countChanged(); }
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include <QQuickView> #include <QtQml> #include <QDebug> #include "database.h" #include "querymodel1.h" #include "datamapper1.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; DataBase database; database.connectToDataBase(); engine.load(QUrl(QLatin1String("qrc:/main.qml"))); QObject *rootObject = engine.rootObjects().first(); qDebug()<<"корневой объект1"<< rootObject; ListModel *model2 = new ListModel(rootObject); DataMapper1 *mapper12 = new DataMapper1(rootObject); QObject::connect(rootObject, SIGNAL(qmlSignal2()), model2, SLOT (updateModel())); mapper12->setModel(model2); engine.rootContext()->setContextProperty("listModel", model2); engine.rootContext()->setContextProperty("mapper", mapper12); engine.rootContext()->setContextProperty("database", &database); //engine.load(QUrl(QLatin1String("qrc:/main.qml"))); return app.exec(); }
После запуска список загружается из базы, фильтрация работает, но данные при клике по элементу списку не передаются в Label{id:text2}. В логах пишет: qrc:/main.qml:239: ReferenceError: mapper is not defined, qrc:/main.qml:162: ReferenceError: listModel is not defined
Если в main.cpp раскомментить предпоследнюю строку, то есть загрузить приложение дважды, то одно из загруженных приложений работает как и задумано.
Очень прошу помощи в решении проблемы!
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.Вам это нравится? Поделитесь в социальных сетях!
Комментарии
Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Пожалуйста, авторизуйтесь или зарегистрируйтесь
AD
- Akiv Doros
- 11 ноября 2024 г. 14:58
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:50баллов,
- Очки рейтинга-4
m
- molni99
- 26 октября 2024 г. 1:37
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:80баллов,
- Очки рейтинга4
m
- molni99
- 26 октября 2024 г. 1:29
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:20баллов,
- Очки рейтинга-10
Последние комментарии
ИМ
Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Игорь Максимов22 ноября 2024 г. 11:51
Evgenii Legotckoi31 октября 2024 г. 14:37
Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
Игорь Максимов5 октября 2024 г. 7:51
QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Сейчас обсуждают на форуме
Evgenii Legotckoi24 июня 2024 г. 15:11
t
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
tonypeachey115 ноября 2024 г. 6:04
NSProject4 июня 2022 г. 3:49
IscanderChe31 октября 2024 г. 15:43
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
День добрый.
Ну так загружать приложение нужно один раз. Вы в моём примере видели две строки?
Первую строку удалить, а вторую раскомментировать.
Это я как пример привел. Если вторую закомментировать, то получаю: qrc:/main.qml:239: ReferenceError: mapper is not defined, qrc:/main.qml:162: ReferenceError: listModel is not defined. Данные в Label из ListView не передаются. Если сделать как вы говорите - первую удалить, а вторую раскомментировать, то И понять причину никак не могу.
Замечательно. Это не пример - это диверсия. Вы намеренно запутали меня, подсунув совершенно другую проблему и не описав, что конкретно у вас происходит.
В примере по QMLDataMapper в файле main.cpp есть одна строка:
Эта строка заполняет модель данных и маппер работает с данными из модели. Вполне вероятно, что как раз и не хватает подобной строки строки. Чтобы забрать первоначальные данные.
Извините, ни в коем случае не хотел вас запутать. Спасибо за наводку, буду думать.
Да ничего.
Просто описывайте проблему без дополнительных изысканий. Зачастую это уводит от сути проблемы. Если бы это не уводило от сути проблемы, то у Вас просто не возникло бы необходимости в консультации, Вы и так бы сразу поняли, где ошибка.
Здесь, скорее всего идёт попытка забрать данные до того, как они были загружены в Маппер, там попросту пусто. Имеет смысл внимательно посмотреть код на предмет последовательности получения данных.
Cпасибо, вроде разобрался! :)